然后再运行测试:
/** * 实现Lock接口方法并运行排他锁测试 * * @author 湘王 */public class MyExclusiveLockTester {// 用自定义AQS独占锁实现private Lock lock = new MyExclusiveLock();private int value;public int accmulator() {lock.lock();try {++value;} finally {lock.unlock();}return value;}public static void main(String[] args) throws InterruptedException {MyExclusiveLockTester test = new MyExclusiveLockTester();for (int i = 0; i < 5; i++) {new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(test.accmulator());}}}).start();}}}可以看到 , 结果无论怎么样都不会再重复了 。
这个只是简单的累加,接下来用AQS来实现一个实际的生活场景 。比如周末带女票或男票去步行街吃饭,这时候人特别多,需要摇号,而且一次只能进去三张号(不按人头算 , 按叫到的号来算),该怎么实现呢?
可以顺着这个思路:摇号机虽有很多号,但它本质上是个共享资源,很多人可以共享 , 但是每次共享的数量有限 。这其实就是个可以指定数量的共享锁而已 。
既然有了思路,那接下来就好办了 。
/** * 利用AQS实现自定义共享锁 * * @author 湘王 */public class MyShareLock implements Lock {@Overridepublic void lock() {}@Overridepublic void lockInterruptibly() throws InterruptedException {}@Overridepublic boolean tryLock() {return false;}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {return false;}@Overridepublic void unlock() {}@Overridepublic Condition newCondition() {return null;}}还是一样实现Lock接口,但这次是用AQS实现共享锁 。
/** * 内部类继承AQS实现共享锁 * */private static class SyncHelper extends AbstractQueuedSynchronizer {private static final long serialVersionUID = -7357716912664213942L;/*** count表示允许几个线程能同时获得锁*/public SyncHelper(int count) {if (count <= 0) {throw new IllegalArgumentException("锁资源数量必须大于0");}// 设置资源总数setState(count);}/*** 一次允许多少个线程进来,允许数量的线程都能拿到锁 , 其他的线程进入队列*/@Overrideprotected int tryAcquireShared(int acquires) {// 自旋for (;;) {int state = getState();int remain = state - acquires;// 判断剩余锁资源是否已小于0或者CAS执行是否成功if (remain < 0 || compareAndSetState(state, remain)) {return remain;}}}/*** 锁资源的获取和释放要一一对应*/@Overrideprotected boolean tryReleaseShared(int releases) {// 自旋for (;;) {// 获取当前stateint current = getState();// 释放状态state增加releasesint next = current + releases;if (next < current) {// 溢出throw new Error("Maximum permit count exceeded");}// 通过CAS更新state的值// 这里不能用setState()if (compareAndSetState(current, next)) {return true;}}}protected Condition newCondition() {return new ConditionObject();}}然后再来改造之前实现的接口:
/** * 利用AQS实现自定义共享锁 * * @author 湘王 */public class MyShareLock implements Lock {public static int count;private final SyncHelper synchepler = new SyncHelper(count);@Overridepublic void lock() {synchepler.acquireShared(1);}@Overridepublic void lockInterruptibly() throws InterruptedException {synchepler.acquireSharedInterruptibly(1);}@Overridepublic boolean tryLock() {return synchepler.tryAcquireShared(1) > 0;}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {return synchepler.tryAcquireSharedNanos(1, unit.toNanos(time));}@Overridepublic void unlock() {synchepler.releaseShared(1);}@Overridepublic Condition newCondition() {return synchepler.newCondition();}/*** 内部类继承AQS实现共享锁**/private static class SyncHelper extends AbstractQueuedSynchronizer {private static final long serialVersionUID = -7357716912664213942L;/*** count表示允许几个线程能同时获得锁*/public SyncHelper(int count) {if (count <= 0) {throw new IllegalArgumentException("锁资源数量必须大于0");}// 设置资源总数setState(count);}/*** 一次允许多少个线程进来,允许数量的线程都能拿到锁,其他的线程进入队列*/@Overrideprotected int tryAcquireShared(int acquires) {// 自旋for (;;) {int state = getState();int remain = state - acquires;// 判断剩余锁资源是否已小于0或者CAS执行是否成功if (remain < 0 || compareAndSetState(state, remain)) {return remain;}}}/*** 锁资源的获取和释放要一一对应*/@Overrideprotected boolean tryReleaseShared(int releases) {// 自旋for (;;) {// 获取当前stateint current = getState();// 释放状态state增加releasesint next = current + releases;if (next < current) {// 溢出throw new Error("Maximum permit count exceeded");}// 通过CAS更新state的值// 这里不能用setState()if (compareAndSetState(current, next)) {return true;}}}protected Condition newCondition() {return new ConditionObject();}}}
推荐阅读
- 三十九 Java开发学习----SpringBoot整合mybatis
- JavaSPI详解
- oppoa53的像素是多少_oppoa53摄像头参数
- 浙江省干部网络培训学院-义乌干部教育网络学院如何多开操作?
- qq飞车怎么结婚变性,会怎么样(qq飞车手游多少级能结婚)
- 五 Selenium4+Python3系列 - 多窗口处理之句柄切换
- day04-JavaScript01
- qq飞车怎么结婚(qq飞车普通婚礼多少钱)
- iphone13海南免税店多少钱_iphone13海南免税店价格
- 小米10s像素多少_小米10s像素怎么样