java并发之CountDownLatch

CountDownLatch是java同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数num赋予CountDownLatch的构造函数,表示需要同步这num个线程,当这些线程运行到同步点时,对CountDownLatch调用CountDown()方法,使得num-1,当num减为0时,表示所有需要同步的线程均到达同步点,此时被CountDownLatch的await()方法阻塞的线程开始执行。

CountDownLatch是闭锁的一种实现,闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态。它的作用相当于一扇门:在闭锁到达结束状态之前,这扇门始终是关闭的,而且没有任何线程可以通过,当到达结束状态时,这扇门就会打开并允许所有的线程通过。当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。闭锁可以用来确保某些活动都完成后才继续执行,比如:

  1.确保某个计算在其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示“资源R已经被初始化”,而所有需要R的操作都必须在这个闭锁上等待。

  2.确保某个服务在其依赖的所有其它服务都已经启动之后才启动。每个服务都有一个相关的二元闭锁。当启动服务s时,将首先在s依赖的其它服务的闭锁上等待,在所有依赖的服务都启动后会释放闭锁s,这样其它依赖s的服务才能继续执行。

  3.等待直到某个操作的所有参与者(比如,在多玩家游戏中的所有玩家)都就绪再继续执行。在这种情况中,当所有玩家都准备就绪时,闭锁将到达结束状态。

下面是一个示例程序,这个程序计算四个数的和:

思路是把四个数分为两组,分别计算和,然后再对两组的和进行求和,代码如下:

package com.test;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {
	static class Worker extends Thread{
		private CountDownLatch count;
		private int left;
		private int right;
		private int result;
		public Worker(CountDownLatch count, int left,int right) {
			this.count = count;
			this.left = left;
			this.right = right;
		}

		@Override
		public void run() {
			synchronized(count){
				System.out.print(Thread.currentThread().getName()+" : ");
				result = left+right;
				System.out.println("Partial result: "+result);
				count.countDown();
			}
		}
		
		public int getResult(){
			return result;
		}
	}
	
	public static void main(String[] args) throws Exception {	//计算1+2+3+4
		CountDownLatch latch = new CountDownLatch(2);
		Worker worker = new Worker(latch,1,2);
		Worker worker2 = new Worker(latch,3,4);
		worker.start();
		worker2.start();
		
		System.out.println("Main waiting!!");
		latch.await();
		System.out.println("Waiting end,Result is: "+(worker.getResult()+worker2.getResult()));
	}
}

使用FutureTask的代码:

package com.test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class Worker implements Callable<Integer> {
	private int hours = 12;
	private int amount;
	
	@Override
	public Integer call() throws Exception {
		while(hours>0){
			amount++;
			System.out.println("I'm working......"+amount);
			hours--;
			Thread.sleep(100);
		}
		return amount;
	}
	
}

public class FutureTaskTest {
	public static void main(String[] args) {
		Worker worker = new Worker();
		FutureTask<Integer> boss = new FutureTask<Integer>(worker);
		new Thread(boss).start();
		//System.out.println("hello");
		//System.out.println(boss.isDone());
		while(!boss.isDone()){
			try {
				System.out.println("看工人做完了没..........");
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		int amount;
		try{
			amount = boss.get();
			System.out.println("工作完成"+amount);
		}catch(InterruptedException e){
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
}

  

原文地址:https://www.cnblogs.com/lxk2010012997/p/5404317.html