CountDownLatch usage and implementation principle

CountDownLatch is a thread descending lock provided by Java. It encapsulates a tool class for developers to use in special scenarios. It is mainly used for the completion of threads corresponding to other actions since the execution of a certain action.

Steps for usage:

1. Get a CountDownLatch instance and initialize the size to the number of dependent action threads

2. Pass the CountDownLatch instance to the dependent thread

3. Call the CountDownLatch.countDown method after the dependent thread performs the corresponding action

4. Call the CountDownLatch.await method in the main thread

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();
		}
	}
}

The core of CountDownLatch is to use a synchronizer that inherits AbstractQueuedSynchronizer. This design pattern is called the template method (the skeleton of the algorithm is defined in the abstract class, and the specific methods in the skeleton are implemented by the subclass). The template method design pattern can refer to the template method

CountDownLatch.await method

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

The acquireSharedInterruptibly method of the synchronizer is actually the parent class of CountDownLatch.Syn, AbstractQueuedSynchronizer, which is an algorithm skeleton

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

The core of acquireSharedInterruptibly is to call tryAcquireShared implemented by subclasses

Look at the abstract methods tryAcquireShared and tryReleaseShared implemented in CountDownLatch.Syn

        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 method

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

The releaseShared method of the synchronizer is actually the parent class of CountDownLatch.Syn, AbstractQueuedSynchronizer, which is also an algorithm skeleton

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

The core of releaseShared is to call tryReleaseShared implemented by subclasses

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326440342&siteId=291194637