java并发之同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser)
线程同步辅助类,主要学习两点:
semaphore(seməˌfôr)
Semphore s = new Semphore(2);
public class PrintQueue {
private Semaphore semaphore;
private boolean freePrinters[];
private Lock lockPrinters; public PrintQueue(){
semaphore=new Semaphore(3);
freePrinters=new boolean[3];
for (int i=0; i<3; i++){
freePrinters[i]=true;
}
lockPrinters=new ReentrantLock();
} public void printJob (Object document){
try {
semaphore.acquire(); int assignedPrinter=getPrinter(); Long duration=(long)(Math.random()*10);
System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n",Thread.currentThread().getName(),assignedPrinter,duration);
TimeUnit.SECONDS.sleep(duration); freePrinters[assignedPrinter]=true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// Free the semaphore
semaphore.release();
}
}
private int getPrinter() {
int ret=-1; try {
lockPrinters.lock();
for (int i=0; i<freePrinters.length; i++) {
if (freePrinters[i]){
ret=i;
freePrinters[i]=false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lockPrinters.unlock();
}
return ret;
}
}
public class Job implements Runnable {
private PrintQueue printQueue; public Job(PrintQueue printQueue){
this.printQueue=printQueue;
} @Override
public void run() {
System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
}
}
public static void main (String args[]){
PrintQueue printQueue=new PrintQueue();
Thread thread[]=new Thread[12];
for (int i=0; i<12; i++){
thread[i]=new Thread(new Job(printQueue),"Thread "+i);
}
for (int i=0; i<12; i++){
thread[i].start();
}
}
public Semaphore(int permits, boolean fair)
CountDownLatch
public class VideoConference implements Runnable{
private final CountDownLatch controller; public VideoConference(int number) {
controller=new CountDownLatch(number);
}
public void arrive(String name){
System.out.printf("%s has arrived.\n",name); controller.countDown();//调用countDown()方法,使内部计数器减1
System.out.printf("VideoConference: Waiting for %d participants.\n",controller.getCount());
} @Override
public void run() {
System.out.printf("VideoConference: Initialization: %d participants.\n",controller.getCount());
try { controller.await();//等待,直到CoutDownLatch计数器为0 System.out.printf("VideoConference: All the participants have come\n");
System.out.printf("VideoConference: Let's start...\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Participant implements Runnable {
private VideoConference conference; private String name; public Participant(VideoConference conference, String name) {
this.conference=conference;
this.name=name;
}
@Override
public void run() {
Long duration=(long)(Math.random()*10);
try {
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
conference.arrive(name);//每到一个人员,CountDownLatch计数器就减少1
}
}
public static void main(String[] args) {
VideoConference conference = new VideoConference(10);
Thread threadConference = new Thread(conference);
threadConference.start();//开启await()方法,在内部计数器为0之前线程处于等待状态
for (int i = 0; i < 10; i++) {
Participant p = new Participant(conference, "Participant " + i);
Thread t = new Thread(p);
t.start();
}
}
CyclicBarrier
public class Searcher implements Runnable {
private final CyclicBarrier barrier;
@Override
public void run() {
int counter;
System.out.printf("%s: Processing lines from %d to %d.\n",Thread.currentThread().getName(),firstRow,lastRow);
for (int i=firstRow; i<lastRow; i++){
int row[]=mock.getRow(i);
counter=0;
for (int j=0; j<row.length; j++){
if (row[j]==number){
counter++;
}
}
results.setData(i, counter);
}
System.out.printf("%s: Lines processed.\n",Thread.currentThread().getName());
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class Grouper implements Runnable {
private Results results; public Grouper(Results results){
this.results=results;
}
@Override
public void run() {
int finalResult=0;
System.out.printf("Grouper: Processing results...\n");
int data[]=results.getData();
for (int number:data){
finalResult+=number;
}
System.out.printf("Grouper: Total result: %d.\n",finalResult);
}
}
public static void main(String[] args) {
final int ROWS=10000;
final int NUMBERS=1000;
final int SEARCH=5;
final int PARTICIPANTS=5;
final int LINES_PARTICIPANT=2000;
MatrixMock mock=new MatrixMock(ROWS, NUMBERS,SEARCH);//矩阵的声明 Results results=new Results(ROWS);//结果集 Grouper grouper=new Grouper(results);//汇总线程 CyclicBarrier barrier=new CyclicBarrier(PARTICIPANTS,grouper);//栅栏,传入参数含义:线程同步个数,汇总线程 Searcher searchers[]=new Searcher[PARTICIPANTS];
for (int i=0; i<PARTICIPANTS; i++){
searchers[i]=new Searcher(i*LINES_PARTICIPANT, (i*LINES_PARTICIPANT)+LINES_PARTICIPANT, mock, results, 5,barrier);
Thread thread=new Thread(searchers[i]);
thread.start();
}
System.out.printf("Main: The main thread has finished.\n");
}
Mock: There are 999286 ocurrences of number in generated data.
Thread-0: Processing lines from 0 to 2000.
Main: The main thread has finished.
Thread-0: Lines processed.
Thread-1: Processing lines from 2000 to 4000.
Thread-1: Lines processed.
Thread-3: Processing lines from 6000 to 8000.
Thread-3: Lines processed.
Thread-2: Processing lines from 4000 to 6000.
Thread-2: Lines processed.
Thread-4: Processing lines from 8000 to 10000.
Thread-4: Lines processed.
Grouper: Processing results...
Grouper: Total result: 999286.
- 在所有线程到达集合点后接受一个Runnable类型的对象作为后续的执行
- 没有显示调用CountDown()方法
- CountDownLatch一般只能使用一次,CyclicBarrier可以多次使用
Phaser
public class FileSearch implements Runnable {
private String initPath; private String end; private List<String> results; private Phaser phaser; public FileSearch(String initPath, String end, Phaser phaser) {
this.initPath = initPath;
this.end = end;
this.phaser=phaser;
results=new ArrayList<>();
}
@Override
public void run() { phaser.arriveAndAwaitAdvance();//等待所有的线程创建完成,确保在进行文件查找的时候所有的线程都已经创建完成了 System.out.printf("%s: Starting.\n",Thread.currentThread().getName()); // 1st Phase: 查找文件
File file = new File(initPath);
if (file.isDirectory()) {
directoryProcess(file);
} // 如果查找结果为false,那么就把该线程从Phaser中移除掉并且结束该线程的运行
if (!checkResults()){
return;
} // 2nd Phase: 过滤结果,过滤出符合条件的(一天内的)结果集
filterResults(); // 如果过滤结果集结果是空的,那么把该线程从Phaser中移除,不让它进入下一阶段的执行
if (!checkResults()){
return;
} // 3rd Phase: 显示结果
showInfo();
phaser.arriveAndDeregister();//任务完成,注销掉所有的线程
System.out.printf("%s: Work completed.\n",Thread.currentThread().getName());
}
private void showInfo() {
for (int i=0; i<results.size(); i++){
File file=new File(results.get(i));
System.out.printf("%s: %s\n",Thread.currentThread().getName(),file.getAbsolutePath());
}
// Waits for the end of all the FileSearch threads that are registered in the phaser
phaser.arriveAndAwaitAdvance();
}
private boolean checkResults() {
if (results.isEmpty()) {
System.out.printf("%s: Phase %d: 0 results.\n",Thread.currentThread().getName(),phaser.getPhase());
System.out.printf("%s: Phase %d: End.\n",Thread.currentThread().getName(),phaser.getPhase());
//结果为空,Phaser完成并把该线程从Phaser中移除掉
phaser.arriveAndDeregister();
return false;
} else {
// 等待所有线程查找完成
System.out.printf("%s: Phase %d: %d results.\n",Thread.currentThread().getName(),phaser.getPhase(),results.size());
phaser.arriveAndAwaitAdvance();
return true;
}
}
private void filterResults() {
List<String> newResults=new ArrayList<>();
long actualDate=new Date().getTime();
for (int i=0; i<results.size(); i++){
File file=new File(results.get(i));
long fileDate=file.lastModified(); if (actualDate-fileDate<TimeUnit.MILLISECONDS.convert(1,TimeUnit.DAYS)){
newResults.add(results.get(i));
}
}
results=newResults;
}
private void directoryProcess(File file) {
// Get the content of the directory
File list[] = file.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
// If is a directory, process it
directoryProcess(list[i]);
} else {
// If is a file, process it
fileProcess(list[i]);
}
}
}
}
private void fileProcess(File file) {
if (file.getName().endsWith(end)) {
results.add(file.getAbsolutePath());
}
}
}
public static void main(String[] args) {
Phaser phaser = new Phaser(3); FileSearch system = new FileSearch("C:\\Windows", "log", phaser);
FileSearch apps = new FileSearch("C:\\Program Files", "log", phaser);
FileSearch documents = new FileSearch("C:\\Documents And Settings", "log", phaser); Thread systemThread = new Thread(system, "System");
systemThread.start();
Thread appsThread = new Thread(apps, "Apps");
appsThread.start();
Thread documentsThread = new Thread(documents, "Documents");
documentsThread.start();
try {
systemThread.join();
appsThread.join();
documentsThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Terminated: %s\n", phaser.isTerminated());
}
java并发之同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser)的更多相关文章
- java并发之同步辅助类CyclicBarrier和CountDownLatch
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门, ...
- java并发之同步辅助类CountDownLatch
CountDownLatch 含义: CountDownLatch可以理解为一个计数器在初始化时设置初始值,当一个线程需要等待某些操作先完成时,需要调用await()方法.这个方法让线程进入休眠状态直 ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semphore、Phaser)
我在<jdk1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)
我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- Java并发之同步工具类
1. CountDownlatch(计数器) 描述: 一个同步工具类,允许一个或多个线程等待其它线程完成操作 类图 通过指定的count值进行初始化,调用await方法的线程将被阻塞,直到count值 ...
- 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)
在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...
- Java并发之同步原语
volatile: 定义:Java编程语言允许线程访问共享变量,为了确保共享变量内被准确和一致性地更新,线程应该确保通过排它锁单独获得这个变量.根据volatile的定义,volatile有锁的语义. ...
- Java并发编程的4个同步辅助类
Java并发编程的4个同步辅助类(CountDownLatch.CyclicBarrier.Semphore.Phaser) @https://www.cnblogs.com/lizhangyong/ ...
- 同步工具类 CountDownLatch 和 CyclicBarrier
在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...
随机推荐
- Sqoop1.99.7将MySQL数据导入到HDFS中
准备 本示例将实现从MySQL数据库中将数据导入到HDFS中 参考文档: http://sqoop.apache.org/docs/1.99.7/user/Sqoop5MinutesDemo.html ...
- sa账户和密码丢失如何找回
来自:http://www.cnblogs.com/xred/archive/2012/03/09/2386185.html 在网上看了很多如何修改SQLServer2005的密码的方法.大多数都是转 ...
- win10 uwp 简单MasterDetail
中文 English 本文主要讲实现一个简单的界面,可以在窗口比较大显示列表和内容,窗口比较小时候显示列表或内容.也就是在窗口比较小的时候,点击列表会显示内容,点击返回会显示列表. 先放图,很简单. ...
- JS中的类型识别
JS为弱类型语言,所以类型识别对JS而言尤为重要,JS中常用的类型识别方法有4种:typeof.Object.prototype.toString.constructor和instanceof. (1 ...
- ArcGIS二次开发AO软件安装破解教程
最近在做ArcGIS二次开发时,采用C#中的WPF技术,在调研中发现ArcGIS 10.3及以上版本支持WPF技术,但是关于ArcGIS10.3的破解教程甚少,自己尝试了不少方法都失败了,淘@宝@商家 ...
- MySQL数据库主从复制实践
MySQL 主从(MySQL Replication),主要用于 MySQL 的实时备份.高可用HA.读写分离.在配置主从复制之前需要先准备 2 台 MySQL 服务器. 一.MySQL主从原 ...
- Mysql Explain 参数解释
查询计划使用以及使用说明 table:显示这一行数据是关于哪张表的. type:显示使用了何种类型,从最好到最差的连接类型为system.const.eq_ref.ref.fulltext.ref_o ...
- SpringMVC 异常的处理
Spring MVC处理异常有3种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver: (2)实现Spring的异常处理接口Hand ...
- HTML5的Websocket(理论篇 I)
HTML5的Websocket(理论篇 I) ** 先请来TA的邻居:** http:无状态.基于tcp请求/响应模式的应用层协议 (A:哎呀,上次你请我吃饭了么? B:我想想, 上次请你吃了么) t ...
- xmanager 打开centos7图形化窗口
centos7 最小化安装后,个别时候需要执行一些带图形界面的命令.比如安装oracle,打开xclock等. 前置条件:centos7系统 ,xmanager 已安装 用xclock做测试 1.因为 ...