zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    【Docker】解析器指令之 escape
    【Docker】解析器指令之 syntax
    【Docker】Dockerfile 解析器指令
    【Docker】Dockerfile 格式
    【Docker】Dockerfile 介绍
    【Docker】Spring Boot 和 Docker
    【Docker】理解 Docker 中的 OverlayFS
    【Docker】使用 OverlayFS 存储驱动
    【Docker】选择存储驱动
    kuangbin专题 专题一 简单搜索 Fire! UVA
  • 原文地址:https://www.cnblogs.com/umgsai/p/5671644.html
Copyright © 2011-2022 走看看