CountDownLatch使用及实现原理

CountDownLatch是Java提供的线程递减锁,为开发人员封装出来针对特殊场景使用的工具类,主要用在某一个动做的执行以来其余动做对应线程的完成。java

使用步骤:算法

1.拿到一个CountDownLatch实例,初始化大小为依赖的动做线程数设计模式

2.将CountDownLatch实例传递给依赖线程ide

3.在依赖线程执行完对应的动做后调用CountDownLatch.countDown方法工具

4.在主线程中调用CountDownLatch.await方法ui

package com.jv.parallel.feature;

import java.util.concurrent.CountDownLatch;

/*
 * 线程递减锁,用来控制某一个动做的执行依赖其余动做线程的完成
 * 
 * 例如:开始钓鱼以前先要作主线、拌饵料、打窝子
 */
public class TestCountDownLatch {
	public static void main(String[] args) throws InterruptedException {
		// 1.声明一个线程递减锁
		// 由于在钓鱼
		CountDownLatch cdl = new CountDownLatch(3);
		new Thread(new TieLine(cdl)).start();
		new Thread(new MixedFood(cdl)).start();
		new Thread(new Feed(cdl)).start();
		cdl.await();
		System.out.println("开始愉快的钓鱼了");
	}
	
	/*
	 * 制做钓鱼的主线
	 */
	static class TieLine implements Runnable{
		CountDownLatch cdl;
		public TieLine(CountDownLatch cdl) {
			this.cdl = cdl;
		}

		@Override
		public void run() {
			System.out.println("制做4.5的主线");
			cdl.countDown();
		}
		
	}
	
	/*
	 * 拌饵料
	 */
	static class MixedFood implements Runnable{
		CountDownLatch cdl;
		public MixedFood(CountDownLatch cdl) {
			this.cdl = cdl;
		}

		@Override
		public void run() {
			System.out.println("拌饵料");
			cdl.countDown();
		}
	}
	
	/*
	 * 作窝子
	 */
	static class Feed implements Runnable{
		CountDownLatch cdl;
		public Feed(CountDownLatch cdl) {
			this.cdl = cdl;
		}

		@Override
		public void run() {
			System.out.println("打窝子");
			cdl.countDown();
		}
	}
}

CountDownLatch核心是使用了一个继承AbstractQueuedSynchronizer的同步器,这种设计模式称之为模板方法(在抽象类中定义算法的骨架,由子类实现骨架中具体的方法),模板方法设计模式能够参阅模板方法this

CountDownLatch.await方法.net

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

同步器的acquireSharedInterruptibly方法实际上是CountDownLatch.Syn父类AbstractQueuedSynchronizer的,它就是一个算法骨架线程

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

acquireSharedInterruptibly的核心就是调用子类实现的tryAcquireShared设计

再看CountDownLatch.Syn中实现的抽象方法tryAcquireShared,tryReleaseShared

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

        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }

CountDownLatch.countDown方法

public void countDown() {
        sync.releaseShared(1);
    }

同步器的releaseShared方法实际上是CountDownLatch.Syn父类AbstractQueuedSynchronizer的,它也是一个算法骨架

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

releaseShared的核心就是调用子类实现的tryReleaseShared

相关文章
相关标签/搜索