Phaser类详解
Phaser允许并发多阶段任务。Phaser类机制是在每一步结束的位置对线程进行同步,当所有的线程都完成了这一步,才允许执行下一步。
一个Phaser对象有两种状态:
- 活跃态(Active):当存在参与同步的线程的时候,Phaser就是活跃的,并且在每个阶段结束的时候进行同步。
- 终止态(Termination):当所有参与同步的线程都取消注册的时候,Phaser就处于终止态,在终止状态下,Phaser没有任何参与者。当Phaser对象onAdvance()方法返回True时,Phaser对象就处于终止态。当Phaser处于终止态时,同步方法arriveAndAwaitAdvance()会立即返回,而且不会做任何同步操作。
Phaser对象的主要方法:
- arrive():这个方法通知phaser对象一个参与者已经完成当前阶段,但是它不应该等待其他参与者都完成当前阶段任务。必须使用这个方法,因为它不会与其他线程同步。
- awaitAdvance(int phase).如果传入的参数与当前阶段一直,这个方法将会将当前线程置于休眠,直到这个阶段的参与者都完成运行。如果传入的阶段参数与当前阶段不一致,立即返回。
- arriveAndAwaitAdvance().当一个线程调用此方法时,Phaser对象将减1,并把这个线程至于休眠状态,直到所有其他线程完成这个阶段。
- arriveAndDeregister().当一个线程调用此方法时,Phaser对象将减1,并且通知这个线程已经完成了当前语句,不会参加到下一个阶段中,因此phaser对象在开始下一个阶段时不会等待这个线程。
- awaitAdvanceInterruptibly(int phase).这个方法跟awaitAdvance(int phase)一样,不同之处是,如果这个方法中休眠的线程被中断,它将抛出InterruptedException异常。
- register():这个方法将一个新的参与者注册到phaser中,这个新的参与者将被当成没有执行完本阶段的线程。
- bulkRegister(int Parties):这个方法将指定数目的参与者注册到Phaser中,所有的这些参与者都讲被当成没有执行完本阶段的线程。
下面将通过具体的实例来讲解Phaser的用法。在实例中Phaser将同步三个并发任务。这三个任务将在三个不同的文件夹及其子文件夹中查找过去24小时内改过扩展名为。log的文件。这个任务分解为三个步骤:
1.在指定文件夹及其子文件夹中获得扩展名为.log的文件。
2.对第一步的结果过滤,删除修改时间超过24小时的文件。
3.将结果打印数据到控制台。
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;
this.results = new ArrayList<String>();
} private void direactoryProcess(File file) {
File list[] = file.listFiles();
if (list != null) {
for (File file2 : list) {
if (file2.isDirectory()) {
direactoryProcess(file2);
} else {
fileProcess(file2);
}
}
}
} private void fileProcess(File file) {
if (file.getName().endsWith(end)) {
results.add(file.getAbsolutePath());
}
} private void filterResult() {
List<String> newResult = new ArrayList<String>();
long actualDate = new Date().getTime();
for (int i = 0; i < results.size(); i++) {
File file = new File(results.get(i));
long lastModifyTime = file.lastModified();
if (actualDate - lastModifyTime < TimeUnit.MICROSECONDS.convert(1,
TimeUnit.DAYS)) {
newResult.add(results.get(i));
}
}
results = newResult;
} private boolean checkResults() {
if (results.isEmpty()) {
System.out.println(Thread.currentThread().getName() + ": Phase "
+ phaser.getPhase() + " 0 result");
System.out.println(Thread.currentThread().getName() + ": Phase "
+ phaser.getPhase() + " end");
phaser.arriveAndDeregister();
return false;
} else {
System.out.println(Thread.currentThread().getName() + ": Phase "
+ phaser.getPhase() + " " + results.size() + " result");
phaser.arriveAndAwaitAdvance();
return true;
}
} private void showInfo() {
for (int i = 0; i < results.size(); i++) {
System.out.println(Thread.currentThread().getName() + ":"
+ results.get(i));
}
phaser.arriveAndAwaitAdvance();
} @Override
public void run() {
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName()+": Starting");
File file=new File(initPath);
if(file.isDirectory()){
direactoryProcess(file);
}
if(!checkResults()){
return;
}
filterResult();
if(!checkResults()){
return;
}
showInfo();
phaser.arriveAndDeregister();
System.out.println(Thread.currentThread().getName()+": Work completed");
}
}
public class PhaserMain {
public static void main(String[] args) {
Phaser phaser=new Phaser(3);
FileSearch system=new FileSearch("c:\\Windows", "log", phaser);
FileSearch apps=new FileSearch("C:\\Programs 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 (Exception e) {
e.printStackTrace();
}
System.out.println("Terminated:"+ phaser.isTerminated());
}
}
Phaser类详解的更多相关文章
- java之StringBuffer类详解
StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...
- java之AbstractStringBuilder类详解
目录 AbstractStringBuilder类 字段 构造器 方法 public abstract String toString() 扩充容量 void expandCapacity(in ...
- java之StringBuilder类详解
StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...
- Java String类详解
Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...
- QAction类详解:
先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...
- JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表
一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...
- Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解
1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...
- C# 内置 DateTime类详解
C# 内置 DateTime类详解 摘抄自微软官方文档,用来方便自己查阅:网址:https://msdn.microsoft.com/zh-cn/library/system.datetime(v=v ...
- Android游戏开发之旅 View类详解
Android游戏开发之旅 View类详解 自定义 View的常用方法: onFinishInflate() 当View中所有的子控件 均被映射成xml后触发 onMeasure(int, int) ...
随机推荐
- JDBC与ArrayList和hashmao
JDBC帮助类 package work; import java.beans.Statement;import java.sql.Connection;import java.sql.DriverM ...
- 使用 ipdb 调试 Python
1.安装 pip install ipdb 2.使用 python -m ipdb xxx.py 程序内部: from ipdb import set_trace set_trace() 3.常用命令 ...
- Kickstart无人值守安装系统
1.导言 已经或未来将从事Linux系统运维工作的读者,经常会遇到一些机器式的重复的共走,例如:有时间同时上线几十甚至上百台服务器,而且需要我们在短时间内完成系统安装. q 光盘安装系统===> ...
- 老李分享:pep8 python代码规范
老李分享:pep8 python代码规范 什么是PEPPEP是 Python Enhancement Proposal 的缩写,翻译过来就是 Python增强建议书 . PEP8 译者:本文基于 20 ...
- 老李案例分享:MAT分析应用程序服务出现内存溢出过程
老李案例分享:MAT分析应用程序服务出现内存溢出过程 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loa ...
- 通过一个小游戏开始接触Python!
之前就一直嚷嚷着要找视频看学习Python,可是一直拖到今晚才开始....好好加油吧骚年,坚持不一定就能有好的结果,但是不坚持就一定是不好的!! 看着视频学习1: 首先,打开IDLE,在IDLE中新建 ...
- 从零到实现Shiro中Authorization和Authentication的缓存
本文大纲 一.简介 二.缓存的概念 三.自定义实现缓存机制 四.什么是Ehcache 五.Ehcache怎么用 六.Spring对缓存的支持 七.Spring+Ehcache实现 八.Spring+S ...
- JSSDK微信自定义分享
背景:15年之前的微信分享只需要加入一段js就可以实现.后来微信官方全部禁止了.现在的微信分享全部得使用jssdk. 一.分享功能: 在微信内(必须在微信里)打开网站页面,分享给朋友或者分享到朋友圈时 ...
- 【转载】 stm32之PWM
发现这位博主的博客被大量的转发,我也转载一篇,谁叫人家写的好呢. 原文地址:http://blog.sina.com.cn/s/blog_49cb42490100s6uh.html 脉冲宽度调制(PW ...
- Android sdk配置 常见问题及处理方法
1. 下载sdk压缩包,解压后显示 2.双击SDK Manager.exe 程序进入如下界面 注:有的童鞋可能遇到如下问题 一般将一和二两种操作都完成就OK了 一. 更新sdk,遇到了更新下载失败问题 ...