通过AQS实现自定义锁
一、前提知识
通过AQS实现自定义锁,目前仅实现了lock和unlock , 如果你读过AQS源码,以ReentrantLock为例:(abstract static class Sync extends AbstractQueuedSynchronizer)(static final class FairSync extends Sync),
例如ReentrantLock、CountDownLatch、Semaphore等 都是自己对抽象类AbstractQueuedSynchronizer进行了自己的实现,AQS的核心是CAS+volatile,这里所谓的CAS是因为在多线程的情况下,没有使用synchronized来同步而是使用了
大量的CAS操作(例如线程节点获取锁和加到尾节点上都使用了CAS操作),内部还维护了一个双向链表有头节点和尾节点,定义了一个 private volatile int state 具体的含义由子类自己决定,ReentrantLock中state的含义是:当state
等于0时证明当前锁没有任何的线程占有,state=1时,证明有线程占有这把锁,记住这里因为ReentrantLock具有可重入性,所以重入一次state加一,当state减少至0时,释放锁。
二、具体的实现
1、自定义锁 这里仅仅实现了lock和unlock。
package com.dongliang.juc.c_021_02_AQS; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; /** * @author D-L * @description: 通过AQS实现自定义锁,目前仅实现了lock和unlock * @date 2020-11-22 13:59:18 */ public class MyLock implements Lock, java.io.Serializable{ private static final long serialVersionUID = 7373984872572414699L; private static final class MySync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; @Override protected boolean tryAcquire(int arg) { if(compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } @Override protected boolean tryRelease(int arg) { setExclusiveOwnerThread(null); setState(0); return true; } @Override protected boolean isHeldExclusively() { return getState() == 1; } } private MySync sync = new MySync(); @Override public void lock() { sync.acquire(1); } @Override public void unlock() { sync.release(1); } @Override public void lockInterruptibly() throws InterruptedException { } @Override public boolean tryLock() { return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return false; } @Override public Condition newCondition() { return null; } }
2、测试方法:通过多线程对int值进行操作。
package com.dongliang.juc.c_021_02_AQS; import java.util.concurrent.locks.Lock; /** * @author D-L * @description: 对自定义锁测试 * @date 2020-11-22 14:10:18 */ public class MyLockTest { public static int m = 0; public static Lock lock = new MyLock(); public static void main(String[] args) throws Exception { Thread[] threads = new Thread[100]; for(int i=0; i<threads.length; i++) { threads[i] = new Thread(()->{ try { //执行lock方法 lock.lock(); for (int j = 0; j < 100; j++) m++; } finally { //出现异常需要手动释放锁 lock.unlock(); } }); } //启动线程 for(Thread t : threads) t.start(); for (Thread t : threads) t.join(); System.out.println(m); } }