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

相關文章
相關標籤/搜索