读JAVA并发包之AbstractQueuedSynchronizer,有更新

java.util.concurrent.ThreadPoolExecutor内部类Worker继承了AbstractQueuedSynchronizer,这个不说了,说说ReentrantLock吧。

从创建锁对象开始,有的同学之前已经注意到了,创建对象的时候是可以加参数的。

 

ReentrantLock rl1=new ReentrantLock(false);
ReentrantLock rl2=new ReentrantLock(true);


如果是true的时候返回公平锁,否则返回非公平锁,到了这里我就看不懂了,什么是公平锁,什么又是非公平锁呢。

 

查看了代码后,发现代码上是有区别的,先上公平锁的代码

 

final void lock() {
            acquire(1);
        }
        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
       protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

这里注意那段e文的注释:
tryacquire的公平版本。不要授权访问,除非递归调用或没有等待者(Runnable)或者是第一个。

 

再对比看看非公平版的:

 

final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }

再看看nonfairTryAcquire这个方法

 

 

final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

Performs non-fair tryLock.  tryAcquire is implemented in subclasses, but both need nonfair try for trylock method.实现非公平trylock。tryacquire是在子类中实现,但都需要非公平实现tryLock方法,这句有待斟酌。
对比代码发现以下

 

1.公平模式下tryacquire判断条件上多了hasQueuedPredecessors()这个方法。

2.非公平模式下lock方法先执行了compareAndSetState(0, 1)方法。
hasQueuedPredecessors() 这个方法是用来查询是否有比当前线程等待了更长时间。返回true,说明当前线程前面有一个排队的线程,返回false说明当前线程是队列中的头结点或者队列为空。

也就是说公平模式下是谁等待的时间长谁优先,类似FIFO的性质,而非公平模式下则是谁先抢到谁执行了(红色部分待验证)

下面来看看compareAndSetState(0, 1)方法如果当前状态值等于期望值自动设置同步状态的更新;此操作具有读取的内存

 

看一下Node中的状态

        /** waitStatus value to indicate thread has cancelled */
        static final int CANCELLED =  1;
        /** waitStatus value to indicate successor's thread needs unparking */
        static final int SIGNAL    = -1;
        /** waitStatus value to indicate thread is waiting on condition */
        static final int CONDITION = -2;
        /**
         * waitStatus value to indicate the next acquireShared should
         * unconditionally propagate
         */
        static final int PROPAGATE = -3;

 

最近有朋友推荐了下面这篇,打算看完后更新下心得。

https://javadoop.com/2017/06/16/AbstractQueuedSynchronizer/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值