原创转载请注明出处:http://agilestyle.iteye.com/blog/2344591
Phaser提供了动态增减parties计数,这点比CyclicBarrier类操作parties更加方便,通过若干个方法来控制多个线程之间同步运行的结果,还可以实现针对某一个线程取消同步运行的效果,而且支持屏障处等待,在等待时还支持中断或非中断等功能,使用Java并发类对线程进行分组同步控制时,Phaser比CyclicBarrier功能更加强大,推荐使用。
arriveAndAwaitAdvance()
arriveAndAwaitAdvance()作用是当前线程已经到达屏障,在此等待一段时间,等条件满足后继续向下一个屏障继续执行
PhaserTest1.java
package org.fool.java.concurrent.phaser;
import java.util.concurrent.Phaser;
public class PhaserTest1 {
public static class Service {
private Phaser phaser;
public Service(Phaser phaser) {
this.phaser = phaser;
}
public void testMethodA() {
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 void testMethodB() {
try {
System.out.println(Thread.currentThread().getName() + " B1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " B1 end " + System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " B2 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " B2 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class ThreadA implements Runnable {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodA();
}
}
public static class ThreadB implements Runnable {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodA();
}
}
public static class ThreadC implements Runnable {
private Service service;
public ThreadC(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodB();
}
}
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
Service service = new Service(phaser);
Thread t1 = new Thread(new ThreadA(service));
t1.setName("Thread-A");
t1.start();
Thread t2 = new Thread(new ThreadB(service));
t2.setName("Thread-B");
t2.start();
Thread t3 = new Thread(new ThreadC(service));
t3.setName("Thread-C");
t3.start();
}
}
Run
PhaserTest2.java
package org.fool.java.concurrent.phaser;
import java.util.concurrent.Phaser;
public class PhaserTest2 {
public static class Service {
private Phaser phaser;
public Service(Phaser phaser) {
this.phaser = phaser;
}
public void testMethodA() {
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 void testMethodB() {
try {
System.out.println(Thread.currentThread().getName() + " B1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " B1 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class ThreadA implements Runnable {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodA();
}
}
public static class ThreadB implements Runnable {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodA();
}
}
public static class ThreadC implements Runnable {
private Service service;
public ThreadC(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodB();
}
}
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
Service service = new Service(phaser);
Thread t1 = new Thread(new ThreadA(service));
t1.setName("Thread-A");
t1.start();
Thread t2 = new Thread(new ThreadB(service));
t2.setName("Thread-B");
t2.start();
Thread t3 = new Thread(new ThreadC(service));
t3.setName("Thread-C");
t3.start();
}
}
Run
Note:
从运行结果来看,当计数不足时,线程呈阻塞状态,不继续向下运行,因为线程C仅仅执行了一次arriveAndAwaitAdvance()方法导致了这样的结果,所以当出现这样无法继续向下一个屏障继续执行的情况,需要使用arriveAndDeregister()
arriveAndDeregister()
arriveAndDeregister()作用是使当前线程退出,并且使parties值减1。
PhaserTest3.java
package org.fool.java.concurrent.phaser;
import java.util.concurrent.Phaser;
public class PhaserTest3 {
public static class Service {
private Phaser phaser;
public Service(Phaser phaser) {
this.phaser = phaser;
}
public void testMethodA() {
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 void testMethodB() {
try {
System.out.println(Thread.currentThread().getName() + " B1 begin " + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("before arriveAndDeregister(): " + phaser.getRegisteredParties());
phaser.arriveAndDeregister();
System.out.println("after arriveAndDeregister(): " + phaser.getRegisteredParties());
System.out.println(Thread.currentThread().getName() + " B1 end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class ThreadA implements Runnable {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodA();
}
}
public static class ThreadB implements Runnable {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodA();
}
}
public static class ThreadC implements Runnable {
private Service service;
public ThreadC(Service service) {
this.service = service;
}
@Override
public void run() {
service.testMethodB();
}
}
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
Service service = new Service(phaser);
Thread t1 = new Thread(new ThreadA(service));
t1.setName("Thread-A");
t1.start();
Thread t2 = new Thread(new ThreadB(service));
t2.setName("Thread-B");
t2.start();
Thread t3 = new Thread(new ThreadC(service));
t3.setName("Thread-C");
t3.start();
}
}
Run
Reference
Java并发编程核心方法与框架