欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

并发同步器 CountDownLatch的用法

程序员文章站 2022-06-06 21:35:23
...
CountDownlatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待,此场景适用在完成所有任务之后才能继续下面的任务的场景 比如下面田径运动员 只有运动员全部跑完比赛才能 进行下面的成绩统计
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 
 * CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,
 * 每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行
 *
 */
public class CountDownLatchTest1 {
 private  final static int NUM=6;//6个运动员
 	public static void main(String[] args) {
	 CountDownLatch begin=new CountDownLatch(1);
	 CountDownLatch end =new CountDownLatch(NUM);
	 Player[] players=new Player[NUM];
	 for(int i=0;i<NUM;i++)
	    	 players[i]=new Player("aa"+(i+1), begin, end);
	 StatisticScore t=new StatisticScore(players);
	 ExecutorService  excutorService=Executors.newFixedThreadPool(NUM);
	 for(Player p:players)
		 excutorService.execute(p);
	 // 比赛开始
	 begin.countDown();
	 try {
		end.await();
	 } catch (InterruptedException e) {
		 e.printStackTrace();
	 }
	 excutorService.shutdown();
	 //开始统计成绩
	 t.start();
  }
}

接下来是田径运动员
/**
 * 田径运动员
 *
 */

class Player extends Thread implements Comparable<Player>{
	//成绩 
	private int score;
	//名字
	private String name;
	//开始同步计时器
	private CountDownLatch begin;
	//结束同步计时器
	private CountDownLatch end;
	
	public Player(String name,CountDownLatch begin,CountDownLatch end) {
	   this.name=name;
	   this.begin=begin;
	   this.end=end;
	}
	@Override
	public void run() {
	   //
		try {
			//等待口令准备开始
			begin.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		try {
			//开始运动
			System.out.println("运动员["+name+"] 开始跑");
			int n=(int) (Math.random()*50);
			Thread.sleep(n);
			//运动结束
			//成绩为
			score=n;
			System.out.println("运动员["+name+"] 跑完,成绩:"+score+"s");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		end.countDown();
	}
	@Override
	public int compareTo(Player o) {
		return score-o.getScore();
	}
	public int getScore() {
		return score;
	}
	public String getPlayerName(){
		return name;
	}
}


下面是成绩统计类
/**
 * 成绩统计
 */
class StatisticScore extends Thread{
	Player[] players;
	
	public StatisticScore(Player[] players) {
		this.players=players;
	}
	@Override
	public void run() {
		System.out.println("成绩统计排行榜如下:");
	  Arrays.sort(players);//成绩排名
	  for(int i=0;i<players.length;i++){
		  System.out.println("运动员["+players[i].getPlayerName()+"] 第"+(i+1)+"名 成绩:"+players[i].getScore()+"s");
	  }
	}
}

最终运行结果
运动员[aa2] 开始跑
运动员[aa4] 开始跑
运动员[aa5] 开始跑
运动员[aa1] 开始跑
运动员[aa3] 开始跑
运动员[aa6] 开始跑
运动员[aa6] 跑完,成绩:3s
运动员[aa5] 跑完,成绩:5s
运动员[aa4] 跑完,成绩:14s
运动员[aa1] 跑完,成绩:31s
运动员[aa2] 跑完,成绩:33s
运动员[aa3] 跑完,成绩:49s
成绩统计排行榜如下:
运动员[aa6] 第1名 成绩:3s
运动员[aa5] 第2名 成绩:5s
运动员[aa4] 第3名 成绩:14s
运动员[aa1] 第4名 成绩:31s
运动员[aa2] 第5名 成绩:33s
运动员[aa3] 第6名 成绩:49s
相关标签: java 线程