首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

【java并发】juc高级锁机制研讨

2012-09-14 
【java并发】juc高级锁机制探讨?如果允许,则获取锁,如果不允许就阻塞线程,直到同步状态允许获取。修改同步状

【java并发】juc高级锁机制探讨

?

如果允许,则获取锁,如果不允许就阻塞线程,直到同步状态允许获取。

修改同步状态,并且唤醒等待线程。

提供volatile变量 state;? 用于同步线程之间的共享状态。通过CAS和volatile保证其原子性和可见性。对应源码里的定义:

    /**     * 同步状态     */    private volatile int state;    /**     *cas     */    protected final boolean compareAndSetState(int expect, int update) {        // See below for intrinsics setup to support this        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);    }
?

有别于wait和notiry。这里利用jdk1.5开始提供的LockSupport.park()和LockSupport.unpark()的本地方法实现,实现线程的阻塞和唤醒。

根据论文里描述,AQS里将阻塞线程封装到一个内部类Node里。并维护一个CHL Node FIFO队列。CHL队列是一个非阻塞的FIFO队列,也就是说往里面插入或移除一个节点的时候,在并发条件下不会阻塞,而是通过自旋锁和CAS保证节点插入和移除的原子性。实现无锁且快速的插入。关于非阻塞算法可以参考? Java 理论与实践: 非阻塞算法简介。CHL队列对应代码如下:

/** * CHL头节点 */ private transient volatile Node head; /** * CHL尾节点 */ private transient volatile Node tail;

?Node节点是对Thread的一个封装,结构大概如下:

    static final class Node {        /** 代表线程已经被取消*/        static final int CANCELLED =  1;        /** 代表后续节点需要唤醒 */        static final int SIGNAL    = -1;        /** 代表线程在等待某一条件/        static final int CONDITION = -2;        /** 标记是共享模式*/        static final Node SHARED = new Node();        /** 标记是独占模式*/        static final Node EXCLUSIVE = null;        /**         * 状态位 ,分别可以使CANCELLED、SINGNAL、CONDITION、0         */        volatile int waitStatus;        /**         * 前置节点         */        volatile Node prev;        /**         * 后续节点         */        volatile Node next;        /**         * 节点代表的线程         */        volatile Thread thread;        /**         *连接到等待condition的下一个节点         */        Node nextWaiter;    }
?

独占获取:tryAcquire本身不会阻塞线程,如果返回true成功就继续,如果返回false那么就阻塞线程并加入阻塞队列。

?

    public final void acquire(int arg) {        if (!tryAcquire(arg) &&            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//获取失败,则加入等待队列            selfInterrupt();} 
?


?

public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); } ?

public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquire(arg) || doAcquireNanos(arg, nanosTimeout);}?

?

独占模式释放:释放成功会唤醒后续节点

    public final boolean release(int arg) {        if (tryRelease(arg)) {            Node h = head;            if (h != null && h.waitStatus != 0)                unparkSuccessor(h);            return true;        }        return false;    }
?

共享模式

public final void acquireShared(int arg) { if (tryAcquireShared(arg) < 0) doAcquireShared(arg);}

?

public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg); }

??

public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquireShared(arg) >= 0 || doAcquireSharedNanos(arg, nanosTimeout); }

?

public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false; } ?

protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); } protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); } protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); } protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); }

?

final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) {//如果状态位为0,那么尝试获取 if (compareAndSetState(0, acquires)) {//基于CAS获取和修改状态 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;//其他情况下代表获取失败 }?

protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (isFirst(current) && 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; }

?可以看看 非公平锁的不会根据FIFO,而公平锁会判断是否是第一个线程,根据FIFO来执行。

?

?

?

?

参考文献:

The java.util.concurrent Synchronizer Framework

? Java 理论与实践: 非阻塞算法简介

《深入浅出 Java Concurrency》目录

热点排行