java phaser用法_Java并发编程核心方法与框架-phaser的使用

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值