aqs采用模板方式设计模式,需要重写方法
package com.company.aqs;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;public class SelfLock implements Lock {// 静态内部类,自定义同步器private static class Sync extends AbstractQueuedSynchronizer {/*** 获取锁* @param arg* @return*/@Overrideprotected boolean tryAcquire(int arg) {if(compareAndSetState(0,1)){setExclusiveOwnerThread(Thread.currentThread());return true;}else{return false;}}/*** 释放锁* @param arg* @return*/@Overrideprotected boolean tryRelease(int arg) {//判断是否是持有线程释放锁if(getExclusiveOwnerThread() != Thread.currentThread()){throw new RuntimeException();}if(getState() == 0){throw new RuntimeException();}//释放锁setExclusiveOwnerThread(null);setState(0);return true;}@Overrideprotected boolean isHeldExclusively() {return getState() == 1;}// 返回一个Condition,每个condition都包含了一个condition队列Condition newCondition() {return new ConditionObject();}}// 仅需要将操作代理到Sync上即可private final Sync sync = new Sync();public void lock() {System.out.println(Thread.currentThread().getName()+" ready get lock");sync.acquire(1);System.out.println(Thread.currentThread().getName()+" already got lock");}public boolean tryLock() {return sync.tryAcquire(1);}public void unlock() {System.out.println(Thread.currentThread().getName()+" ready release lock");sync.release(1);System.out.println(Thread.currentThread().getName()+" already released lock");}public Condition newCondition() {return sync.newCondition();}public boolean isLocked() {return sync.isHeldExclusively();}public boolean hasQueuedThreads() {return sync.hasQueuedThreads();}public void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);}public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}
}
测试自定义显示锁
package com.company.aqs;import com.company.SleepTools;import java.util.concurrent.locks.Lock;public class TestMyLock {public void test() {final Lock lock = new SelfLock();class Worker extends Thread {public void run() {lock.lock();System.out.println(Thread.currentThread().getName());try {SleepTools.second(1);} finally {lock.unlock();}}}// 启动4个子线程for (int i = 0; i < 3; i++) {Worker w = new Worker();//w.setDaemon(true);w.start();}// 主线程每隔1秒换行for (int i = 0; i < 10; i++) {SleepTools.second(1);//System.out.println();}}public static void main(String[] args) {TestMyLock testMyLock = new TestMyLock();testMyLock.test();}
}
aqs源码分析
acquire方法中线程cas自旋尝试加入aqs队列
acquire方法中队列第一个node争抢锁
acquire方法中获取不到锁,就一直阻塞
release方法唤醒线程执行