通过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);
    }
}

 

posted @ 2020-11-24 17:54  AmourLee  阅读(276)  评论(0编辑  收藏  举报