一、信号同步
多线程很多时候是协作作业。比如4个线程对电商数据分季度统计,统计完成之后,再汇总。如何知道4个线程都执行完成呢,我们可以使用JDK1.5给我们提供的辅助类CountDownLatch(
减少计数)、CyclicBarrier(循环栅栏)、Semaphore(信号灯)。
二、基于时间维度
1、CountDownLatch
多少个协作线程就初始化CountDownLatch的构造参数是多少。
public static void main(String[] args) throws InterruptedException {
final int NUM=6;
//定义总数量;
CountDownLatch countDownLatch=new CountDownLatch(NUM);
for (int i = 0; i < NUM; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"线程,已执行!");
//减少计数
countDownLatch.countDown();
},String.valueOf(i+1)).start();
}
//等待所有任务完成
countDownLatch.await();
System.out.println("所有线程任务已经执行完成!");
}
?
2、CyclicBarrier
与减少计数类似
public static void main(String[] args) {
final int NUM = 6;
//定义循环数量及循环完成后的任务(Runnable接口实现);
CyclicBarrier cyclicBarrier = new CyclicBarrier(NUM, () -> {
System.out.println("所有线程任务已经执行完成!");
});
for (int i = 0; i < NUM; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"线程,已执行!");
try {
//等待点或障碍点,等待所有任务完成,
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i+1)).start();
}
}
三、基于信号维度
Semaphore,线程与信号是m:n,其中m>=n。
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/*信号灯
* 6个线程,抢占三个信号
* */
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore=new Semaphore(3);
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
//获取信号
semaphore.acquire();
System.out.println("线程:"+Thread.currentThread().getName()+"----获取信号");
int time = new Random().nextInt(5);
System.out.println(("线程:"+Thread.currentThread().getName()+"----休眠"+time+"s!"));
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// 释放信号
System.out.println("线程:"+Thread.currentThread().getName()+"---释放信号");
semaphore.release();
}
},String.valueOf(i+1)).start();
}
}
}
?首先线程4、1、3获取到信号,线程1释放信号后,线程2获得信号。线程2、3释放信号后,线程5、6获得信号。
|