并发包的同步组件

1,概述

java并发包已经讲解了volatile,synchronized,CAS,AQS机制等。这些都是整个并发的基础,这篇主要讲一下并发包下的一些组件。

2,CountDownLatch

2.1 demo:

首先演示下这个组件的功能。主线程执行到await()方法后,就会同步等待2个线程执行,这里的2就是构造函数传入的。然后再执行下去。

public class CountDownLatchDemo {
    public static void main(String[] args) throws Exception{
        final CountDownLatch latch = new CountDownLatch(2);

        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println("线程1执行...");
                    latch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println("线程2执行...");
                    latch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }.start();
        System.out.println("主线程即将执行await...");
        latch.await();
        System.out.println("主线程执行...");
    }
}

2.2 构造函数:

    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }
        //将传入的参数作为state的大小。这里的state即AQS下的state
        Sync(int count) {
            setState(count);
        }

2.3 await():

    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

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

这里需要看看tryAcquireShared()方法:

        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

很明显,state是我们传入的2,不等于0,会进入方法doAcquireSharedInterruptibly():

    private void doAcquireSharedInterruptibly(int arg)
        throws InterruptedException {
        final Node node = addWaiter(Node.SHARED);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        failed = false;
                        return;
                    }
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

这个方法前面都分析过,直接画图了:

然后其他线程会执行countDown()方法,源码逻辑很简单,就是依次去减state的值。然后判断state是否等于0,如果state==0,则唤醒队列中main线程。可以发现,熟悉AQS原理之后,这些都是很简单的,所以AQS是并发的基础。

猜你喜欢

转载自www.cnblogs.com/xtz2018/p/11493982.html
今日推荐