Java多线程之CountDownLatch

为了解决多线程问题,java.util.concurrent包从Java SE5开始引入了一个新类CountDownLatch。其功能主要用来同步多个任务的执行顺序,CountDown的意思是倒数计秒,Latch做为名词有门闩锁存器的意思。


锁存器的最主要作用是缓存,其次完成高速的控制其与慢速的外设的不同步问题,再其次是解决驱动的问题,最后是解决一个 I/O 口既能输出也能输入的问题。

因此,顾名思义,CountDownLatch可以在倒数计时期间保持多个任务的执行状态,倒计时结束时便可以解锁并唤醒其他任务。
CountDownLatch最典型的应用就是将一个大的任务分解成N个子任务,当N个子任务执行完毕后可以唤起下一个大任务。
我们将N作为倒数记时的时间来初始化一个CoutDownLatch对象,然后每当一个子任务完成时,可以将N减1,等到N为0的时候,其他正在等待的任务便可以wake up。

Package

import java.util.concurrent.*;



首先,定义一个子任务TaskPortion

private static Random rand = new Random(47);
	private final CountDownLatch latch;

	TaskPortion(CountDownLatch latch) {
		this.latch = latch;
	}

	public void run() {
		try {
			doWork();
			latch.countDown();
		} catch (InterruptedException e) {
			// Acceptable way to exit
		}
	}

	public void doWork() throws InterruptedException {
		TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
		System.out.println(this + "completed");
	}

	public String toString() {
		return String.format("%1$-3d", id);
	}
}


然后,定义一个不同的任务,但是这个任务只有在所有子任务全部完成后才可以执行。
// Waits on the CountDownLatch
class WaitingTask implements Runnable {
	private static int counter = 0;
	private final int id = counter++;
	private final CountDownLatch latch;

	WaitingTask(CountDownLatch latch) {
		this.latch = latch;
	}

	public void run() {
		try {
			latch.await();
			System.out.println("Latch barrier passed for " + this);
		} catch (InterruptedException ex) {
			System.out.println(this + " interrupted");
		}
	}

	public String toString() {
		return String.format("WaitingTask %1$-3d ", id);
	}
}



最后,编写测试代码,通过new 100个TaskPortion来分解一个大的任务,新建10个需要等待的任务。
public class CountDownLatchDemo {
	static final int SIZE = 10;
	public static void main(String[] args) throws Exception {
		ExecutorService exec = Executors.newCachedThreadPool();
		// All must share a single CountDownLatch object:
		CountDownLatch latch = new CountDownLatch(SIZE);
		for (int i = 0; i < 10; i++) {
			exec.execute(new WaitingTask(latch));
		}
		for (int i = 0; i < SIZE; i++) {
			exec.execute(new TaskPortion(latch));
		}
		System.out.println("Launched all tasks");
		exec.shutdown(); // Quit when all tasks complete
	}
}



编译后执行,结果如下。可以看出只有当10个TaskPortion结束之后,WaitingTask才可以继续执行。
Launched all tasks
7  completed
9  completed
5  completed
8  completed
1  completed
2  completed
6  completed
4  completed
0  completed
3  completed
Latch barrier passed for WaitingTask 7   
Latch barrier passed for WaitingTask 9   
Latch barrier passed for WaitingTask 2   
Latch barrier passed for WaitingTask 5   
Latch barrier passed for WaitingTask 8   
Latch barrier passed for WaitingTask 4   
Latch barrier passed for WaitingTask 6   
Latch barrier passed for WaitingTask 0   
Latch barrier passed for WaitingTask 3   
Latch barrier passed for WaitingTask 1   

你可能感兴趣的:(Java多线程之CountDownLatch)