Java并发之CountDownLatch、CyclicBarrier、Semaphore

1、CountDownLatch

解析:

同步倒数计数器 CountDownLatch初始化一个计数器值,其countDown方法会把计数器值减1,  await()方法会阻塞后面程序执行直到计数器值减为0。


Demo:

package com.fedomn.demo;

import java.util.concurrent.CountDownLatch;

public class Worker {
	private final static int WorkerNum = 5;
	
	public static void main(String args[]){
		final CountDownLatch startCountDown = new CountDownLatch(1);
		final CountDownLatch endCountDown = new CountDownLatch(WorkerNum);
		final CountDownLatch workerCountDown = new CountDownLatch(WorkerNum);
		
		for(int i=0;i<WorkerNum;i++){
			new Thread(String.valueOf(i)){
				public void run(){
					workerCountDown.countDown();
					System.out.println("我是工人 "+this.getName()+" 号,已经准备好工作!");
					try {
						startCountDown.await();//等待发出开始工作 指令
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("我是工人 "+this.getName()+" 号,已经完成工作!");
					endCountDown.countDown();
				}
			}.start();
		}
		
		try {
			workerCountDown.await();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println("开始工作!");
		startCountDown.countDown();//发出开始工作 指令
		try {
			endCountDown.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("工作结束!");
	}
}


输出结果:

我是工人 0 号,已经准备好工作!
我是工人 3 号,已经准备好工作!
我是工人 1 号,已经准备好工作!
我是工人 2 号,已经准备好工作!
我是工人 4 号,已经准备好工作!
开始工作!
我是工人 0 号,已经完成工作!
我是工人 2 号,已经完成工作!
我是工人 1 号,已经完成工作!
我是工人 3 号,已经完成工作!
我是工人 4 号,已经完成工作!
工作结束!

2、CyclicBarrier

解析:

1、CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当等待线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续

2、CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍

3、CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行


Demo:

package com.fedomn.demo;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CycWroker {
	private final static int threadNum = 3;
	private final static CyclicBarrier c = new CyclicBarrier(threadNum,new Runnable() {
		public void run() {
			System.out.println("我是Runnable老板!");
		}
	});
	
	public static void main(String args[]){
		for(int i=0;i<threadNum;i++){
			new Thread(String.valueOf(i)){
				public void run() {
					System.out.println("我是工人 "+this.getName()+" 号,工作第一步");
					try {
						c.await();
					} catch (InterruptedException | BrokenBarrierException e) {
						e.printStackTrace();
					}
					
					System.out.println("我是工人 "+this.getName()+" 号,工作 第二步");
					try {
						c.await();
					} catch (InterruptedException | BrokenBarrierException e) {
						e.printStackTrace();
					}
				}	
			}.start();
		}		
	}
}

输出结果:

我是工人 0 号,工作第一步
我是工人 2 号,工作第一步
我是工人 1 号,工作第一步
我是Runnable老板!
我是工人 1 号,工作 第二步
我是工人 0 号,工作 第二步
我是工人 2 号,工作 第二步
我是Runnable老板!


3、Semaphor

解析:

设置一个数字,当请求的数量达到设定数字,就将请求拦截下来,直到有线程释放了资源,才会放一个请求进去。

其中acquire 方法获得许可,release 方法释放许可。其他方法参见API

Demo:

package com.fedomn.demo;

import java.util.concurrent.Semaphore;

public class SemWorker {
	
	private final static Semaphore sem = new Semaphore(3);
	
	public static void main(String[] args) {
		
		for(int i=0;i<10;i++){
			new Thread(String.valueOf(i)){
				public void run() {
					try {
						sem.acquire();//获取一个许可
						System.out.println("我是工人 "+this.getName()+" 号,工作Start!");
						Thread.sleep(1000);
						System.out.println("我是工人 "+this.getName()+" 号,工作End!");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}finally{
						sem.release();//释放一个许可
					}
				}
			}.start();
		}
	}
}

输出结果:

我是工人 0 号,工作Start!
我是工人 5 号,工作Start!
我是工人 1 号,工作Start!
我是工人 5 号,工作End!
我是工人 0 号,工作End!
我是工人 3 号,工作Start!
我是工人 1 号,工作End!
我是工人 4 号,工作Start!
我是工人 2 号,工作Start!
我是工人 2 号,工作End!
我是工人 3 号,工作End!
我是工人 4 号,工作End!
我是工人 6 号,工作Start!
我是工人 7 号,工作Start!
我是工人 8 号,工作Start!
我是工人 6 号,工作End!
我是工人 9 号,工作Start!
我是工人 7 号,工作End!
我是工人 8 号,工作End!
我是工人 9 号,工作End!

4、总结

CountDownLatch:
适用于一组线程和另一个主线程之间的工作协作。一个主线程等待一组工作线程的任务完毕才继续它的执行是使用。
初始化计数器值线程个数,组中每个线程countDown使计数器值到0时,解除await()阻塞,执行主线程后面的程序。

CyclicBarrier:

适用于一组或几组线程在一个时间点达到同步,可以一起开始执行下一步任务(如构造函数传入的Runnable)。
初始化等待线程的数目N,组中每个线程await()进入等待,当等待线程为N时,所有等待线程都被唤醒继续执行。

Semaphore:
只允许一定数量的线程同时执行一段任务。
初始化线程允许数量N,每个线程通过acquire()来获得许可,必须等线程release()释放许可,才能接受下一个线程。














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值