- 浏览: 388033 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (285)
- test (0)
- 分类 (1)
- java (281)
- tttttttttttt (1)
- android程序复制数据库 (1)
- Hibernate 动态 HQL (1)
- java编写扑克的洗牌程序 (1)
- NIO 之 选择就绪模式 (1)
- wpo另类问题:不可轻视的蜘蛛爬行对服务器造成的负担 (1)
- haml (1)
- cvcvcvc (1)
- 开源史上最成功的8个开源产品 (1)
- XML文件转换成Word文件或者Excel文件 (1)
- 一些利用开源浏览器核心开发专用浏览器的连接 (1)
- 毛笔效果简单思路 (1)
- 年终考评以后 (1)
- RFC821 简单邮件传输协议(SMTP)中文定义文档 (1)
- JNI中jstring类型与c语言中的字符串的转换 (1)
- 极限编程(XP)的重构与设计模式 (1)
- MapInfo2005年第三期电子新闻 (1)
- 想到目前各BLOG站点和搜索引擎的一点点缺陷 (1)
- 成功通过DB2的700和701考试 (1)
- 基于记录登陆信息的防止网页暴力破解方法 (1)
- Router路由 (1)
- 终于稍微完整的学习了一下Linux (1)
- android手机通讯录备份还原代码 (1)
- Qt之美(一):d指针/p指针详解 (1)
- DB2 静默安装 (1)
- linux开机启动脚本的顺序 (1)
- Hibernate实体对象的三种状态 (1)
- Hibernate面向对象的hql语句 (1)
- ibatIS调用存储过程 (1)
- Linux启动过程(详细说明) (1)
- C3P0配置 (1)
- memcache安装 (1)
- js event.keyCode (1)
- java获取汉子首字母 (1)
- Eclipse GC log (1)
- java轻量级httpserver (1)
最新评论
-
smilea001:
我知道了,作者采用的是gbk编码,我采用的是utf-8编码,
java获取汉子首字母 -
smilea001:
我输入的也是--
java获取汉子首字母 -
di1984HIT:
写的不错啊。
Router路由 -
kaixinyou:
...
2011.07.20——— android 获得当前view在屏幕的坐标 -
zhengjianbo:
你好,可以将你的实现代码公布下吗!万分感谢!
毛笔效果简单思路
1 Overview
Java 7的并发包中推出了Phaser,其功能跟CyclicBarrier和CountDownLatch有些重叠,但是提供了更灵活的用法,例如支持动态调整注册任务的数量等。本文在Phaser自带的示例代码基础上进行一下简单的分析。
2 Glossary
2.1 Registration
Phaser支持通过register()和bulkRegister(int
parties)方法来动态调整注册任务的数量,此外也支持通过其构造函数进行指定初始数量。在适当的时机,Phaser支持减少注册任务的数量,例如
arriveAndDeregister()。单个Phaser实例允许的注册任务数的上限是65535。
2.2 Arrival
正如Phaser类的名字所暗示,每个Phaser实例都会维护一个phase
number,初始值为0。每当所有注册的任务都到达Phaser时,phase
number累加,并在超过Integer.MAX_VALUE后清零。arrive()和arriveAndDeregister()方法用于记录到
达,arriveAndAwaitAdvance()方法用于记录到达,并且等待其它未到达的任务。
2.3 Termination
Phaser支持终止。Phaser终止之后,调用register()和bulkRegister(int
parties)方法没有任何效果,arriveAndAwaitAdvance()方法也会立即返回。触发终止的时机是在protected
boolean onAdvance(int phase, int
registeredParties)方法返回时,如果该方法返回true,那么Phaser会被终止。默认实现是在注册任务数为0时返回true(即
return registeredParties ==
0;)。此外,forceTermination()方法用于强制终止,isTerminated()方法用于判断是否已经终止。
2.4 Tiering
Phaser支持层次结构,即通过构造函数Phaser(Phaser parent)和Phaser(Phaser parent,
int
parties)构造一个树形结构。这有助于减轻因在单个的Phaser上注册过多的任务而导致的竞争,从而提升吞吐量,代价是增加单个操作的开销。
3 Sample Usage
3.1 Sample 1
在有些场景下,我们希望控制多个线程的启动时机:例如在并发相关的单元测试中,有时需要控制线程的启动时机,以期获得最大程度的并发,通常我们会使用CountDownLatch,以下是使用Phaser的版本。
import java.util.concurrent.Phaser;
public class PhaserTest1 {
public static void main(String args[]) {
//
final int count = 5;
final Phaser phaser = new Phaser();
for(int i = 0; i < count; i++) {
System.out.println("starting thread, id: " + i);
phaser.register();
final Thread thread = new Thread(new Task(i, phaser));
thread.start();
}
}
public static class Task implements Runnable {
//
private final int id;
private final Phaser phaser;
public Task(int id, Phaser phaser) {
this.id = id;
this.phaser = phaser;
}
@Override
public void run() {
phaser.arriveAndAwaitAdvance();
System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " + this.id);
}
}
}
以上例子中,由于线程是在一个循环中start,因此start的时机有一定的间隔。本例中这些线程实际开始工作的时机是在所有的线程都调用了phaser.arriveAndAwaitAdvance()之后。
此外,如果留心arriveAndAwaitAdvance()方法的签名,会发现它并没有抛出InterruptedException,实际上,即使
当前线程被中断,arriveAndAwaitAdvance()方法也不会返回,而是继续等待。如果在等待时希望可中断,或者可超时,那么需要使用以下
方法:
awaitAdvance(arrive()) // 等效于arriveAndAwaitAdvance()
awaitAdvanceInterruptibly(int phase)
awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit)
3.2 Sample 2
有些时候我们希望只有在某些外部条件满足时,才真正开始任务的执行,例如:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.Phaser;
public class PhaserTest2 {
public static void main(String args[]) throws Exception {
//
final Phaser phaser = new Phaser(1);
for(int i = 0; i < 5; i++) {
phaser.register();
System.out.println("starting thread, id: " + i);
final Thread thread = new Thread(new Task(i, phaser));
thread.start();
}
//
System.out.println("Press ENTER to continue");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
phaser.arriveAndDeregister();
}
public static class Task implements Runnable {
//
private final int id;
private final Phaser phaser;
public Task(int id, Phaser phaser) {
this.id = id;
this.phaser = phaser;
}
@Override
public void run() {
phaser.arriveAndAwaitAdvance();
System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " + this.id);
}
}
}
以上例子中,只有当用户按下回车之后,任务才真正开始执行。需要注意的是,arriveAndDeregister()方法不会被阻塞,并且返回到达时的phase number(arrive方法也是如此)。
3.3 Sample 3
CyclicBarrier支持barrier action, Phaser同样也支持。不同之处是Phaser的barrier action需要改写onAdvance方法来进行定制。
import java.util.concurrent.Phaser;
public class PhaserTest3 {
public static void main(String args[]) throws Exception {
//
final int count = 5;
final int phaseToTerminate = 3;
final Phaser phaser = new Phaser() {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("====== " + phase + " ======");
return phase >= phaseToTerminate || registeredParties == 0;
}
};
//
for(int i = 0; i < count; i++) {
System.out.println("starting thread, id: " + i);
phaser.register();
final Thread thread = new Thread(new Task(i, phaser));
thread.start();
}
}
public static class Task implements Runnable {
//
private final int id;
private final Phaser phaser;
public Task(int id, Phaser phaser) {
this.id = id;
this.phaser = phaser;
}
@Override
public void run() {
do {
try {
Thread.sleep(500);
} catch(InterruptedException e) {
// NOP
}
System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " + this.id);
phaser.arriveAndAwaitAdvance();
} while(!phaser.isTerminated());
}
}
}
本例中的barrier action只是简单地打印了一条信息,此外在超过指定的迭代次数后终止了Phaser。
3.4 Sample 4
在Smaple 3的例子中,主线程在其它工作线程结束之前已经终止。如果希望主线程等待这些工作线程结束,除了使用Thread.join()之外,也可以尝试以下的方式:
import java.util.concurrent.Phaser;
public class PhaserTest4 {
public static void main(String args[]) throws Exception {
//
final int count = 5;
final int phaseToTerminate = 3;
final Phaser phaser = new Phaser() {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("====== " + phase + " ======");
return phase == phaseToTerminate || registeredParties == 0;
}
};
//
for(int i = 0; i < count; i++) {
System.out.println("starting thread, id: " + i);
phaser.register();
final Thread thread = new Thread(new Task(i, phaser));
thread.start();
}
//
phaser.register();
while (!phaser.isTerminated()) {
phaser.arriveAndAwaitAdvance();
}
System.out.println("done");
}
public static class Task implements Runnable {
//
private final int id;
private final Phaser phaser;
public Task(int id, Phaser phaser) {
this.id = id;
this.phaser = phaser;
}
@Override
public void run() {
while(!phaser.isTerminated()) {
try {
Thread.sleep(500);
} catch(InterruptedException e) {
// NOP
}
System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " + this.id);
phaser.arriveAndAwaitAdvance();
}
}
}
}
如果希望主线程在特定的phase结束之后终止,那么可以在主线程中调用下述方法:
public static void awaitPhase(Phaser phaser, int phase) {
int p = phaser.register(); // assumes caller not already registered
while (p < phase) {
if (phaser.isTerminated()) {
break; // ... deal with unexpected termination
} else {
p = phaser.arriveAndAwaitAdvance();
}
}
phaser.arriveAndDeregister();
}
需要注意的是,awaitPhase方法中的if (phaser.isTerminated())
分支里需要能够正确处理Phaser终止的情况。否则由于在Phaser终止之后,
phaser.register()和arriveAndAwaitAdvance()方法均返回负值,那么上述方法可能陷入死循环。
3.5 Sample 5
以下对Phaser进行分层的例子:
import java.util.concurrent.Phaser;
public class PhaserTest6 {
//
private static final int TASKS_PER_PHASER = 4;
public static void main(String args[]) throws Exception {
//
final int phaseToTerminate = 3;
final Phaser phaser = new Phaser() {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("====== " + phase + " ======");
return phase == phaseToTerminate || registeredParties == 0;
}
};
//
final Task tasks[] = new Task[10];
build(tasks, 0, tasks.length, phaser);
for (int i = 0; i < tasks.length; i++) {
System.out.println("starting thread, id: " + i);
final Thread thread = new Thread(tasks[i]);
thread.start();
}
}
public static void build(Task[] tasks, int lo, int hi, Phaser ph) {
if (hi - lo > TASKS_PER_PHASER) {
for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
int j = Math.min(i + TASKS_PER_PHASER, hi);
build(tasks, i, j, new Phaser(ph));
}
} else {
for (int i = lo; i < hi; ++i)
tasks[i] = new Task(i, ph);
}
}
public static class Task implements Runnable {
//
private final int id;
private final Phaser phaser;
public Task(int id, Phaser phaser) {
this.id = id;
this.phaser = phaser;
this.phaser.register();
}
@Override
public void run() {
while (!phaser.isTerminated()) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// NOP
}
System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " + this.id);
phaser.arriveAndAwaitAdvance();
}
}
}
}
需要注意的是,TASKS_PER_PHASER的值取决于具体的Task实现。对于Task执行时间很短的场景(也就是竞争相对激烈),可以考虑使用较小的TASKS_PER_PHASER值,例如4。反之可以适当增大TASKS_PER_PHASER。
发表评论
-
java轻量级httpserver
2012-02-08 11:48 1564httpclient+httpserver demo ... -
Eclipse GC log
2012-02-04 16:59 1395为了查看Eclipse GC log,需要在eclip ... -
java获取汉子首字母
2012-02-03 09:14 1520public class StringUtil { ... -
js event.keyCode
2012-02-03 09:09 1201<span style="" ... -
memcache安装
2012-02-02 12:04 1143? <blockquote> 1. ... -
C3P0配置
2012-02-02 11:34 981cquireIncrement[3] ... -
Linux启动过程(详细说明)
2012-02-01 09:09 1560<div class="post ... -
ibatIS调用存储过程
2012-01-31 15:38 1603<p>一、ibatIS调用存储过程(调用存 ... -
Hibernate面向对象的hql语句
2012-01-11 13:14 997Hibernate中hql条件语句的书写方式有: ? ... -
Hibernate实体对象的三种状态
2012-01-11 12:59 1271<p style="text- ... -
linux开机启动脚本的顺序
2011-12-21 15:14 1101下开机自动启动脚本所涉及的知识和方法、如下: ... -
DB2 静默安装
2011-12-21 11:59 1051<span style="color: ... -
Qt之美(一):d指针/p指针详解
2011-12-20 15:14 1945[/b]2011.11.16 [size=18px;] ... -
android手机通讯录备份还原代码
2011-12-20 11:54 2939<span style="font-f ... -
终于稍微完整的学习了一下Linux
2011-12-19 12:14 1167Linux以前也装过两次,不过几乎没去用。头几天看一些 ... -
Router路由
2011-12-19 10:54 1157Router路由:设定线的轨迹,在Connection ... -
基于记录登陆信息的防止网页暴力破解方法
2011-12-17 10:49 1431对黑客方面比较感兴趣的或者是比较熟悉的,应该知道溯雪这 ... -
成功通过DB2的700和701考试
2011-12-16 17:27 859嘿嘿,原以为比较没有信心的701考试也被俺成功的攻克了 ... -
想到目前各BLOG站点和搜索引擎的一点点缺陷
2011-12-15 15:54 872感觉无聊,就到中国博客网的首页逛了逛,想看看有没有什么 ... -
MapInfo2005年第三期电子新闻
2011-12-15 10:49 895<span lang="EN-US&q ...
相关推荐
Java Virtual Machine Support for Non-Java Languages: Java SE 7 introduces a new JVM instruction that simplifies the implementation of dynamically typed programming languages on the JVM. Garbage-First...
of how to use the new Java 7 Phaser class to synchronize tasks divided into phases. Chapter 4, Thread Executors will teach the readers to delegate the thread management to executors. They allow ...
Get to grips with exciting new concurrency features of Java 7, including the Phaser Class and the Fork/Join Framework Successfully delegate thread management to executors Customize some of the most ...
主要介绍了java多线程之Phaser的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
phaser-inspector, Phaser检查器插件允许你检查Phaser游戏 Phaser检查器插件将重新设计 [UPDATE] Phaser检查器插件重新设计和重构,以使它的成为更好的插件。 [UPDATE] Phaser检查器插件支持RenderTexture上的。 ...
使用 Phaser HTML5 game framework 製做的刮刮樂範例程式
java7在并发编程方面,带来了很多令人激动的新功能,这将使你的应用程序具备更好的并行任务性能。 《Java 7并发编程实战手册》是Java 7并发编程的实战指南,介绍了Java 7并发API中大部分重要而有用的机制。全书分为9...
Phaser3.22最新版
最新版本的phaser文件
Phaser的伟大的开源游戏开发框架,使用HTML5创建游戏。这是一款利用Phaser.js制作仿Nokia经典的贪吃蛇游戏。
phaser.min.js,免费,实用,提供phaser.min.js,前端JS
富士施乐(xerox) phaser3155驱动软件,英文版
phaser开发最新版本库文件
phaser2.4.4版本 html5游戏编写利器
Xerox富士施乐Phaser 3200MFP激光打印机驱动For Vista-64。
用 phaser 3 游戏引擎开发的 《围住神经猫》 代码来源于: https://github.com/ganlvtech/phaser-catch-the-cat 我提供的是基于此代码的修改版,修改内容:支持手机端全屏操作。 (原代码在PC浏览器中显示正常,...
Node.js上的相位器 ...安装并需要phaser和@geckos.io/phaser-on-nodejs 。 确保在服务器上以无头模式使用Phaser { type: Phaser.HEADLESS } require ( '@geckos.io/phaser-on-nodejs' ) const Phase
基于phaser的H5小游戏趣味反弹球,包括小球和障碍物的创建、障碍物强度和小球数量升级,单H5文件结构简单易懂,适合独立小游戏开发的快速上手
phaser HTML5 2D游戏引擎框架
富士施乐3116驱动是由富士施乐官方专门为富士施乐xeroxphaser3116型号打印机打造的打印机驱动程序,如果您打印机无法正常打印或者不能连接电脑,您可以下载phaser3116驱动,即可快速帮你解决这类问题。富士施乐...