一、信号同步
多线程很多时候是协作作业。比如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
与减少计数类似
立即学习“Java免费学习笔记(深入)”;
临沂奥硕软件有限公司拥有国内一流的企业网站管理系统,奥硕企业网站管理系统真正会打字就会建站的管理系统,其强大的扩展性可以满足企业网站实现各种功能(唯一集成3O多套模版的企业建站系统)奥硕企业网站管理系统具有一下特色功能1、双语双模(中英文采用单独模板设计,可制作中英文不同样式的网站)2、在线编辑JS动态菜单支持下拉效果,同时生成中文,英文,静态3个JS菜单3、在线制作并调用FLASH展示动画4、自
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获得信号。











