quartz-SimpleSemaphore

public class InterruptThread2 extends Thread{

    public static void main(String[] args) {
        try {
            Semaphore1 lockHandler = new SimpleSemaphore();
            InterruptThread2 t = new InterruptThread2(lockHandler,"TRIGGER_ACCESS");
            t.start();
            InterruptThread2 t1 = new InterruptThread2(lockHandler,"TRIGGER_ACCESS");
            t1.start();
            InterruptThread2 t2 = new InterruptThread2(lockHandler,"TRIGGER_ACCESS");
            t2.start();
            InterruptThread2 t3 = new InterruptThread2(lockHandler,"TRIGGER_ACCESS");
            t3.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    Semaphore1 lockHandler;
    String name;
    InterruptThread2(Semaphore1 lockHandler,String name){
        this.lockHandler=lockHandler;
        this.name=name;
    }
    
    public void run() {
        super.run();
            try {
                lockHandler.obtainLock(name);//只有一个线程完全释放了锁,下个线程才会获取到锁。
            } catch (LockException e) {
                e.printStackTrace();
            }
            try {
                lockHandler.releaseLock(name);//obtainLock()和releaseLock()是synchronized锁住的是同一个对象。获取锁和释放锁的线程只有一个线程能进去。
            } catch (LockException e) {
                e.printStackTrace();
            }
    }
}
public class SimpleSemaphore implements Semaphore1 {

    ThreadLocal lockOwners = new ThreadLocal();

    HashSet locks = new HashSet();

    private final Logger log = LoggerFactory.getLogger(getClass());

    protected Logger getLog() {
        return log;
    }

    private HashSet getThreadLocks() {
        HashSet threadLocks = (HashSet) lockOwners.get();
        if (threadLocks == null) {
            threadLocks = new HashSet();
            lockOwners.set(threadLocks);
        }
        return threadLocks;
    }

    public synchronized boolean obtainLock(String lockName) {//这里就会加synchronized锁,只能一个线程进来。里面的代码不会有线程安全问题,因为只有一个线程进到这里来。
        lockName = lockName.intern();//上一个线程还没有释放锁,下一个线程可以进来这里,但是获取不到锁,会wait.
        Logger log = getLog();

        if (!isLockOwner(lockName)) {//这个线程从来没有进来过,或者进来了但是release了,已经从ThreadLocal移除了。
            if (log.isDebugEnabled()) {
                log.debug("Lock '" + lockName + "' is being obtained: " + Thread.currentThread().getName());
            }
            while (locks.contains(lockName)) {//只要其他线程没有释放锁releaseLock(),locks就会存着这个线程的lockName,locks是所有线程公用的变量,调用releaseLock()从locks移除,releaseLock()和obtainLock()方法公用一把锁。
                try {
                    this.wait();//其他线程都在这里等。locks里面只有一个值,不会有多个值。
                } catch (InterruptedException ie) {
                    if (log.isDebugEnabled()) {
                        log.debug("Lock '" + lockName + "' was not obtained by: " + Thread.currentThread().getName());
                    }
                }
            }

            getThreadLocks().add(lockName);//线程对象
            locks.add(lockName);
        }  

        return true;
    }

    public synchronized void releaseLock(String lockName) {//获取锁释放锁,用的是同一把锁,
        lockName = lockName.intern();
        if (isLockOwner(lockName)) {
            if (getLog().isDebugEnabled()) {
                getLog().debug("Lock '" + lockName + "' retuned by: " + Thread.currentThread().getName());
            }
            getThreadLocks().remove(lockName);
            locks.remove(lockName);
            this.notifyAll();//唤醒通过synchronized锁住的线程。就是SimpleSemaphore对象。
        } 
    }

    public synchronized boolean isLockOwner(String lockName) {
        lockName = lockName.intern();
        return getThreadLocks().contains(lockName);
    }

    public boolean requiresConnection() {
        return false;
    }
}

 

posted @ 2020-08-20 10:47  无天666  阅读(477)  评论(0编辑  收藏  举报