CountDownLatch 与 CyclicBarrier应用

CountDownLatch

        一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
        用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。
        问题:老师组织一次考试,做完题目的学生就可以交卷,然后可以去做自己的事情。老师则要等所有的学生交完试卷后才能整理试卷。
        下面使用CountDownLatch来模拟上面的问题。

  1. 老师类:负责在全部学生交卷后整理试卷
/**
 * 老师
 * @author sky
 *
 */
public class Teacher implements Runnable {

	@Override
	public void run() {
		System.out.println("老师整理试卷");
		
	}
}
2. 学生类:做题,做完后交卷,之后自由活动
import java.util.concurrent.CountDownLatch;
public class Student implements Runnable{
	/**
	 * 考试学生名称
	 */
	private String name;
	/**
	 * 接下来要做的事
	 */
	private String nextThing;
	/**
	 * 做题时间
	 */
	private int time ;
	
	private CountDownLatch latch;
	
	public  Student(String n,String nt,CountDownLatch c,int t){
		this.name = n;
		this.nextThing = nt;
		this.latch = c;
		this.time = t;
	}

	@Override
	public void run() {
		System.out.println(name+" 考试中");
		try {
			Thread.sleep(time*1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name+" 交卷了,花费时间:"+time+"秒");
		latch.countDown();
		System.out.println(name+" 去"+nextThing);
	}
}

3.考试类
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Exam {

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		int sNum = 3;
		CountDownLatch latch = new CountDownLatch(sNum);
		ExecutorService service = Executors.newFixedThreadPool(sNum);
		String [] names ={"A","B","C"};
		String [] nextThing = {"吃饭","打魔兽","看xiaoy解说"};
		System.out.println("开始考试了");
		Student student;
		for (int i = 0; i < sNum; i++) {
			student = new Student(names[i], nextThing[i], latch,i+1);
			service.submit(student);
		}
		latch.await();
		service.submit(new Teacher());
		service.shutdown();
	}
}
4.输出:
开始考试了
B 考试中
A 考试中
C 考试中
A 交卷了,花费时间:1秒
A 去吃饭
B 交卷了,花费时间:2秒
B 去打魔兽
C 交卷了,花费时间:3秒
C 去看xiaoy解说
老师整理试卷
CyclicBarrier
        一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。 

        CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。 

        接着用上面考试的问题,但是有一点不同,学生在昨晚试卷后不能马上交卷,要等所有学生都做完后才能一起交卷。

        使用CyclicBarrier实现方式:

1. 老师类:负责在全部学生交卷后整理试卷(无变化微笑

public class Teacher implements Runnable {

	@Override
	public void run() {
		System.out.println("老师整理试卷");
		
	}
}

2. 学生类:做题,等待所有学生都做完题目后一起交卷,之后自由活动

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Student implements Runnable{
	/**
	 * 考试学生名称
	 */
	private String name;
	/**
	 * 接下来要做的事
	 */
	private String nextThing;
	/**
	 * 做题需要时间
	 */
	private int time;
	
	private CyclicBarrier barrier;
	
	public  Student(String n,String nt,CyclicBarrier c,int t){
		this.name = n;
		this.nextThing = nt;
		this.barrier = c;
		this.time=t;
	}

	@Override
	public void run() {
		System.out.println(name+" 考试中");
		try {
			Thread.sleep(time*1000L);
			System.out.println(name+" 交卷了,花费时间:"+time+"秒");
			barrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
		System.out.println(name+" 去"+nextThing);
	}
}

3. 考试类

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Exam {

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		int sNum = 3;
		CyclicBarrier barrier = new CyclicBarrier(sNum,new Teacher());
		ExecutorService service = Executors.newFixedThreadPool(sNum);
		String [] names ={"A","B","C"};
		String [] nextThing = {"吃饭","打魔兽","看xiaoy解说"};
		System.out.println("开始考试了");
		Student student;
		for (int i = 0; i < sNum; i++) {
			student = new Student(names[i], nextThing[i], barrier,i+1);
			service.submit(student);
		}
		service.shutdown();
	}
}

4. 输出

开始考试了
A 考试中
C 考试中
B 考试中
A 交卷了,花费时间:1秒
B 交卷了,花费时间:2秒
C 交卷了,花费时间:3秒
老师整理试卷
A 去吃饭
B 去打魔兽
C 去看xiaoy解说




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值