CountDownLatch :一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化 CountDownLatch
。调用 countDown()
使当前计数减1,在到达0之前,await
方法会一直受阻塞。之后,会释放所有等待的线程,await
的所有后续调用都将立即返回。
如 一个任务A,它要等待其他N个任务执行完毕之后才能执行,则可以用 CountDownLatch。
利用 CountDownLatch 计算 1+2+3+4+.....+n 的值,代码如下:
package com.zewe.countdownLatch;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 多线程计算 1+2+3+4+5+......+n 的值
* @author ZeWe
*
*/
public class CountDownLatchTest {
private static Integer sum = 0;
private static Integer n = 10005;
private static Integer latchSize = 10; //线程数量
private static CountDownLatch latch;
private static Lock lock;
public static void main(String[] args) throws InterruptedException {
lock = new ReentrantLock();
latch = new CountDownLatch(latchSize);
int avg = n / latchSize;
int rem = n % latchSize;
int left,right;
for(int i = 1; i<=latchSize; i++) {
left = (i-1)*avg+1;
right = i == latchSize ? (i*avg+rem) : (i*avg);
new Thread(new Run(left,right)).start();
}
latch.await(); // 等待10个进程完全结束,在进行主线程
System.out.println(Thread.currentThread().getName()+"--> sum:"+sum);
}
static class Run implements Runnable{
private int left;
private int right;
public Run(int left,int right) {
this.left = left;
this.right = right;
}
@Override
public void run() {
int res = 0;
for(int i=left; i<=right; i++) {
res+=i;
}
lock.lock(); // static sum 并发相加 加锁
try {
sum+=res;
System.out.println(Thread.currentThread().getName()+"--> left:"+left+", right:"+right+", res:"+res+", sum: "+sum);
latch.countDown(); // 完成一个 减去一个
} finally {
lock.unlock();
}
}
}
}
结果:
Thread-0--> left:1, right:1000, res:500500, sum: 500500
Thread-9--> left:9001, right:10005, res:9550515, sum: 10051015
Thread-1--> left:1001, right:2000, res:1500500, sum: 11551515
Thread-2--> left:2001, right:3000, res:2500500, sum: 14052015
Thread-3--> left:3001, right:4000, res:3500500, sum: 17552515
Thread-4--> left:4001, right:5000, res:4500500, sum: 22053015
Thread-5--> left:5001, right:6000, res:5500500, sum: 27553515
Thread-6--> left:6001, right:7000, res:6500500, sum: 34054015
Thread-7--> left:7001, right:8000, res:7500500, sum: 41554515
Thread-8--> left:8001, right:9000, res:8500500, sum: 50055015
main--> sum:50055015