1. 程式人生 > >模仿Semaphore自定義自己的 信號量

模仿Semaphore自定義自己的 信號量

run 利用 信號 created pos system ted package sleep

簡介

這裏模仿Semaphore,自定義自己的信號量,利用AQS共享模式

1、MySemaphore.java

package com.jacky;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * Created by jacky on 2018/2/13.
 */
public class MySemaphore {

    private Sync sync;

    public MySemaphore(int permits){
       sync 
= new NonFairSync(permits); } public MySemaphore(int permits,boolean fair){ sync = fair ? new FairSync(permits) : new NonFairSync(permits); } static class Sync extends AbstractQueuedSynchronizer{ Sync(int permits) { setState(permits); } @Override
protected boolean tryReleaseShared(int arg) { for (;;){ int oldState = getState(); int newState = oldState+arg; if (compareAndSetState(oldState,newState)){ return true; } } } }
static final class FairSync extends Sync{ FairSync(int permits) { super(permits); } @Override protected int tryAcquireShared(int arg) { for(;;){ if (hasQueuedPredecessors()){ return -1; } int oldState = getState(); int newState = oldState-arg; if (newState <0 || compareAndSetState(oldState,newState)){ return newState; } } } } static final class NonFairSync extends Sync{ NonFairSync(int permits) { super(permits); } @Override protected int tryAcquireShared(int arg) { for(;;){ int oldState = getState(); int newState = oldState-arg; if (newState <0 || compareAndSetState(oldState,newState)){ return newState; } } } } /** * 獲取許可證 */ public void acquire(){ try { sync.acquireSharedInterruptibly(1); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 釋放許可證 */ public void release(){ sync.releaseShared(1); } }

2、測試

package com.jacky;

import java.util.concurrent.Semaphore;

/**
 * Created by jacky on 2018/2/12.
 */
public class SemaphoreDemo {
    public static void main(String[] args) {
        //Semaphore semaphore = new Semaphore(2, true);
        MySemaphore semaphore = new MySemaphore(2, true);
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Thread thread = Thread.currentThread();
                System.out.println("semaphore start:"+thread.getName());
                try {
                    semaphore.acquire();
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                semaphore.release();
                System.out.println("semaphore end:"+thread.getName());

            }
        };

        for (int i=0;i<10;i++){
            Thread thread = new Thread(runnable, "t" + i);
            thread.start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

模仿Semaphore自定義自己的 信號量