arriveAndAwaitAdvance()方法

arriveAndAwaitAdvance()作用是当前线程已经到达屏障,在此等待一段时间,等条件满足后继续向下一个屏障执行。

public class PrintTools {
public static Phaser phaser;
public static void methodA() {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " A2 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A2 end " + System.currentTimeMillis());
} public static void methodB() {
try {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " A2 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A2 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public class ThreadA extends Thread {
@Override
public void run() {
PrintTools.methodA();//执行A方法
}
} public class ThreadB extends Thread {
@Override
public void run() {
PrintTools.methodA();//执行A方法
}
} public class ThreadC extends Thread {
@Override
public void run() {
PrintTools.methodB();//执行B方法
}
} public class Main {
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
PrintTools.phaser = phaser;
ThreadA a = new ThreadA();
a.setName("A");
a.start();
ThreadB b = new ThreadB();
b.setName("B");
b.start();
ThreadC c = new ThreadC();
c.setName("C");
c.start();
}
}

程序运行结果如下:

A A1 begin 1469711023742
B A1 begin 1469711023742
C A1 begin 1469711023743
C A1 end 1469711028745
A A1 end 1469711028745
B A1 end 1469711028745
A A2 begin 1469711028745
C A2 begin 1469711028745
B A2 begin 1469711028745
B A2 end 1469711033748
C A2 end 1469711033748
A A2 end 1469711033748

A、B线程会等待C线程一起到达屏障点,然后一起继续向下执行。

对以上代码做如下修改:

public class PrintTools {
public static Phaser phaser;
public static void methodA() {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " A2 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A2 end " + System.currentTimeMillis());
} public static void methodB() {
try {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
/* C提前退出比赛
System.out.println(Thread.currentThread().getName() + " A2 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A2 end " + System.currentTimeMillis());
*/
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//其他代码保持不变

重新运行程序,控制台打印结果如下:

A A1 begin 1469711274416
B A1 begin 1469711274416
C A1 begin 1469711274417
B A1 end 1469711279421
C A1 end 1469711279421
A A1 end 1469711279421
B A2 begin 1469711279421
A A2 begin 1469711279421

A、B到达第二个屏障点后等不到C的到来,程序不结束,将会一直等下去。


arriveAndDeregister()方法

arriveAndDeregister()方法的作用是使线程退出比赛,并且使parties值减1

对以上代码做如下修改:

public class PrintTools {
public static Phaser phaser;
public static void methodA() {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " A2 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A2 end " + System.currentTimeMillis());
} public static void methodB() {
try {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("A:" + phaser.getRegisteredParties());
phaser.arriveAndDeregister();//退出比赛
System.out.println("B:" + phaser.getRegisteredParties());
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//其他代码保持不变

程序运行结果如下:

A A1 begin 1469711921794
B A1 begin 1469711921795
C A1 begin 1469711921795
A:3
B:2
B A1 end 1469711926799
C A1 end 1469711926799
A A1 end 1469711926799
B A2 begin 1469711926799
A A2 begin 1469711926800
B A2 end 1469711926800
A A2 end 1469711926800

此时程序可以正常结束。


onAdvance()方法
public class MyService {
private Phaser phaser;
public MyService(Phaser phaser) {
super();
this.phaser = phaser;
} public void testMethod() {
try {
System.out.println("阶段1 Begin " + Thread.currentThread().getName() + System.currentTimeMillis());
if (Thread.currentThread().getName().equals("B")) {
Thread.sleep(5000);
}
phaser.arriveAndAwaitAdvance();
System.out.println("阶段1 End " + Thread.currentThread().getName() + " end phase value=" + phaser.getPhase() + " " + System.currentTimeMillis());
/********/
System.out.println("阶段2 Begin " + Thread.currentThread().getName() + System.currentTimeMillis());
if (Thread.currentThread().getName().equals("B")) {
Thread.sleep(5000);
}
phaser.arriveAndAwaitAdvance();
System.out.println("阶段2 End " + Thread.currentThread().getName() + " end phase value=" + phaser.getPhase() + " " + System.currentTimeMillis());
/********/
System.out.println("阶段3 Begin " + Thread.currentThread().getName() + System.currentTimeMillis());
if (Thread.currentThread().getName().equals("B")) {
Thread.sleep(5000);
}
phaser.arriveAndAwaitAdvance();
System.out.println("阶段3 End " + Thread.currentThread().getName() + " end phase value=" + phaser.getPhase() + " " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} //省略ThreadA、ThreadB
public class Main {
public static void main(String[] args) {
Phaser phaser = new Phaser(2){
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("onAdvance 被" + Thread.currentThread().getName() + "调用 " + System.currentTimeMillis() + " phase value=" + phase + " registeredParties=" + registeredParties);
return false;
//返回true 不等待,Phaser呈无效/销毁的状态
//返回false则Phaser继续工作
}
};
MyService service = new MyService(phaser);
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}

运行程序,控制台打印结果如下:

阶段1 Begin A1470103011668
阶段1 Begin B1470103011669
onAdvance 被B调用 1470103016670 phase value=0 registeredParties=2
阶段1 End B end phase value=1 1470103016670
阶段1 End A end phase value=1 1470103016670
阶段2 Begin A1470103016670
阶段2 Begin B1470103016670
onAdvance 被B调用 1470103021675 phase value=1 registeredParties=2
阶段2 End B end phase value=2 1470103021675
阶段2 End A end phase value=2 1470103021675
阶段3 Begin A1470103021675
阶段3 Begin B1470103021675
onAdvance 被B调用 1470103026677 phase value=2 registeredParties=2
阶段3 End B end phase value=3 1470103026677
阶段3 End A end phase value=3 1470103026677

onAdvance()在B线程到达屏障点时被调用。如果在onAdvance()方法中返回true,Phaser会被销毁。

对main函数中的代码做如下修改:

public class Main {
public static void main(String[] args) {
Phaser phaser = new Phaser(2){
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("onAdvance 被" + Thread.currentThread().getName() + "调用 " + System.currentTimeMillis() + " phase value=" + phase + " registeredParties=" + registeredParties);
return true;
//返回true 不等待,Phaser呈无效/销毁的状态
//返回false则Phaser继续工作
}
};
MyService service = new MyService(phaser);
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}

重新运行程序,控制台打印结果如下:

阶段1 Begin A1470103416899
阶段1 Begin B1470103416899
onAdvance 被B调用 1470103421901 phase value=0 registeredParties=2
阶段1 End B end phase value=-2147483647 1470103421901
阶段1 End A end phase value=-2147483647 1470103421901
阶段2 Begin B1470103421901
阶段2 Begin A1470103421901
阶段2 End A end phase value=-2147483647 1470103421901
阶段3 Begin A1470103421901
阶段3 End A end phase value=-2147483647 1470103421902
阶段2 End B end phase value=-2147483647 1470103426905
阶段3 Begin B1470103426905
阶段3 End B end phase value=-2147483647 1470103431907

arrive()方法

arrive()方法的作用是使parties值加1,并且不在屏障处等待,直接向下面的代码继续运行,并且充值Phaser类的计数。

public class Run {
public static void main(String[] args) {
Phaser phaser = new Phaser(2){
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("到达了未通过!phase=" + phase + " registeredParties=" + registeredParties);
return super.onAdvance(phase, registeredParties);
}
};
System.out.println("A1,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
phaser.arrive();
System.out.println("A1,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
System.out.println("A2,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
phaser.arrive();
System.out.println("A2,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
//---------
System.out.println("B1,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
phaser.arrive();
System.out.println("B1,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
System.out.println("B2,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
phaser.arrive();
System.out.println("B2,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
//---------
System.out.println("C1,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
phaser.arrive();
System.out.println("C1,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
System.out.println("C2,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
phaser.arrive();
System.out.println("C2,getPhase=" + phaser.getPhase() + " getRegisteredParties=" + phaser.getRegisteredParties() + " getArrivedParties=" + phaser.getArrivedParties());
}
}

运行程序,控制台打印结果如下:

A1,getPhase=0 getRegisteredParties=2 getArrivedParties=0
A1,getPhase=0 getRegisteredParties=2 getArrivedParties=1
A2,getPhase=0 getRegisteredParties=2 getArrivedParties=1
到达了未通过!phase=0 registeredParties=2
A2,getPhase=1 getRegisteredParties=2 getArrivedParties=0
B1,getPhase=1 getRegisteredParties=2 getArrivedParties=0
B1,getPhase=1 getRegisteredParties=2 getArrivedParties=1
B2,getPhase=1 getRegisteredParties=2 getArrivedParties=1
到达了未通过!phase=1 registeredParties=2
B2,getPhase=2 getRegisteredParties=2 getArrivedParties=0
C1,getPhase=2 getRegisteredParties=2 getArrivedParties=0
C1,getPhase=2 getRegisteredParties=2 getArrivedParties=1
C2,getPhase=2 getRegisteredParties=2 getArrivedParties=1
到达了未通过!phase=2 registeredParties=2
C2,getPhase=3 getRegisteredParties=2 getArrivedParties=0

方法arrive()的功能是使getArrivedParties()计数加1,不等待其他线程到达屏障。控制台多次出现getArrivedParties=0说明Phaser类经过屏障点后计数被重置。


arriveAdvance(int phase)方法的作用是:如果传入参数phase值和当前getPhase()方法返回值一样,则在屏障处等待,否则继续向下面运行。

public class ThreadA extends Thread {
private Phaser phaser;
public ThreadA(Phaser phaser) {
super();
this.phaser = phaser;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
}
} public class ThreadB extends Thread {
private Phaser phaser;
public ThreadB(Phaser phaser) {
super();
this.phaser = phaser;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
}
} public class ThreadC extends Thread {
private Phaser phaser;
public ThreadC(Phaser phaser) {
super();
this.phaser = phaser;
} @Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
Thread.sleep(3000);
phaser.awaitAdvance(0);//跨栏的栏数。不参与parties计数的操作,仅具有判断功能。
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public class ThreadD extends Thread {
private Phaser phaser;
public ThreadD(Phaser phaser) {
super();
this.phaser = phaser;
} @Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " A1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " A1 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public class Main {
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
ThreadA a = new ThreadA(phaser);
a.setName("A");
a.start();
ThreadB b = new ThreadB(phaser);
b.setName("B");
b.start();
ThreadC c = new ThreadC(phaser);
c.setName("C");
c.start();
ThreadD d = new ThreadD(phaser);
d.setName("D");
d.start();
}
}

程序运行结果如下:

A A1 begin 1470226617412
B A1 begin 1470226617412
C A1 begin 1470226617413
D A1 begin 1470226617414
C A1 end 1470226622416
B A1 end 1470226622416
A A1 end 1470226622416
D A1 end 1470226622416

Java并发编程核心方法与框架-phaser的使用的更多相关文章

  1. Java并发编程核心方法与框架-CountDownLatch的使用

    Java多线程编程中经常会碰到这样一种场景:某个线程需要等待一个或多个线程操作结束(或达到某种状态)才开始执行.比如裁判员需要等待运动员准备好后才发送开始指令,运动员要等裁判员发送开始指令后才开始比赛 ...

  2. Java并发编程核心方法与框架-Fork-Join分治编程(一)

    在JDK1.7版本中提供了Fork-Join并行执行任务框架,它的主要作用是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总,这种开发方法也叫做分治编程,可以极大地利用CPU资源,提高任务 ...

  3. Java并发编程核心方法与框架-TheadPoolExecutor的使用

    类ThreadPoolExecutor最常使用的构造方法是 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAli ...

  4. Java并发编程核心方法与框架-Semaphore的使用

    Semaphore中文含义是信号.信号系统,这个类的主要作用就是限制线程并发数量.如果不限制线程并发数量,CPU资源很快就会被耗尽,每个线程执行的任务会相当缓慢,因为CPU要把时间片分配给不同的线程对 ...

  5. Java并发编程核心方法与框架-CompletionService的使用

    接口CompletionService的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离.使用submit()执行任务,使用take取得已完成的任务,并按 ...

  6. Java并发编程核心方法与框架-ScheduledExecutorService的使用

    类SchedukedExecutorService的主要作用是可以将定时任务与线程池功能结合. 使用Callable延迟运行(有返回值) public class MyCallableA implem ...

  7. Java并发编程核心方法与框架-ExecutorService的使用

    在ThreadPoolExecutor中使用ExecutorService中的方法 方法invokeAny()和invokeAll()具有阻塞特性 方法invokeAny()取得第一个完成任务的结果值 ...

  8. Java并发编程核心方法与框架-Future和Callable的使用

    Callable接口与Runnable接口对比的主要优点是Callable接口可以通过Future获取返回值.但是Future接口调用get()方法取得结果时是阻塞的,如果调用Future对象的get ...

  9. Java并发编程核心方法与框架-Executors的使用

    合理利用线程池能够带来三个好处 降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 提高线程的可管理性.线程是稀 ...

随机推荐

  1. Mysql实现行列转换

    前言: 最近又玩起了sql语句,想着想着便给自己出了一道题目:“行列转换”.起初瞎折腾了不少时间也上网参考了一些博文,不过大多数是采用oracle数据库当中的一些便捷函数进行处理,比如”pivot”. ...

  2. 【bzoj3675】 Apio2014—序列分割

    http://www.lydsy.com/JudgeOnline/problem.php?id=3675 (题目链接) 题意 给出一个包含n个非负整数的序列,要求将其分割成k+1个序列,每次分割可以获 ...

  3. shell命令rm删除非空文件夹

    rm -rf dirName CentOS的自带的资源管理器叫nautilus,在命令行里输入nautilus可以启动它.

  4. 【Alpha阶段】第七次Scrum例会

    会议信息 时间:2016.10.29 21:30 时长:60min 地点:大运村1号公寓5楼楼道 类型:日常Scrum会议 NXT:2016.11.01 21:30 个人任务报告 姓名 今日已完成Is ...

  5. Linux命令:简单函数调用

    脚本编程之函数: function: 功能       结构化编程,不能独立运行,需要调用时执行,可以被多次调用 1.定义一个函数:function FUNCNAME {  command} FUNC ...

  6. wpf 线程

    一.线程概述:[引用MSDN] 通常,WPF 应用程序从两个线程开始:一个用于处理呈现,一个用于管理 UI.呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入.处理事件.绘制屏幕以及运行应用程序代 ...

  7. SQL Server编程(01)流程控制

    批处理 应用程序向SqlServer发送的一组命令,Sql Server会将其编译成一个可执行单元,称为执行计划,执行计划中的语句每次执行一条. 每个不同的批处理用GO命令分割.GO命令不是SQL语句 ...

  8. js006-面向对象的程序设计

    js006-面向对象的程序设计 面向对象(Object-Oriented,OO)的语言有一个标志,那就是他们都有类的概念.而通过类可以创建多个具有相同属性和方法的对象. ECMA-262把对象定义为: ...

  9. python学习笔记-(八)装饰器、生成器&迭代器

    本节课程内容概览: 1.装饰器 2.列表生成式&迭代器&生成器 3.json&pickle数据序列化 1. 装饰器 1.1 定义: 本质上是个函数,功能是装饰其他函数—就是为其 ...

  10. 查看apt-get安装软件的版本

    apt-cache search name 查询 apt-get install name 安装 dpkg dpkg dpkg-checkbuilddeps dpkg-genchanges dpkg- ...