Phaser

1.arriveAndAwaitAdvance()方法

 1 package Three_Phaser_arriveAndDeregister;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Service {
 6 
 7     Phaser phaser;
 8 
 9     public Service(Phaser phaser) {
10         super();
11         this.phaser = phaser;
12     }
13 
14     public void methodA() throws InterruptedException {
15         System.out.println(Thread.currentThread().getName() + "赛程1 开始!!" + System.currentTimeMillis());
16         phaser.arriveAndAwaitAdvance();
17         System.out.println(Thread.currentThread().getName() + "赛程1 结束!!" + System.currentTimeMillis());
18         
19     }
20     
21 }
 1 package Three_Phaser_arriveAndDeregister;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class ThreadA extends Thread {
 6 
 7     private Service service;
 8 
 9     public ThreadA(Service service) {
10         super();
11         this.service = service;
12     }
13 
14     public void run() {
15         try {
16             service.methodA();
17         } catch (InterruptedException e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }
21     }
22 }
23 -----------------------------------------------------------------------------------------
24 package Three_Phaser_arriveAndDeregister;
25 
26 import java.util.concurrent.Phaser;
27 
28 public class ThreadB extends Thread {
29 
30     private Service service;
31 
32     public ThreadB(Service service) {
33         super();
34         this.service = service;
35     }
36 
37     public void run() {
38         try {
39             service.methodA();
40         } catch (InterruptedException e) {
41             // TODO Auto-generated catch block
42             e.printStackTrace();
43         }
44     }
45 }
46 -----------------------------------------------------------------------------------------
47 package Three_Phaser_arriveAndDeregister;
48 
49 import java.util.concurrent.Phaser;
50 
51 public class ThreadC extends Thread {
52 
53     private Service service;
54 
55     public ThreadC(Service service) {
56         super();
57         this.service = service;
58     }
59 
60     public void run() {
61         try {
62             service.methodA();
63         } catch (InterruptedException e) {
64             // TODO Auto-generated catch block
65             e.printStackTrace();
66         }
67     }
68 }
 1 package Three_Phaser_arriveAndDeregister;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Run {
 6     public static void main(String[] args) {
 7         Phaser phaser = new Phaser(2);
 8         Service service = new Service(phaser);
 9 
10         ThreadA a = new ThreadA(service);
11         a.setName("A");
12 
13         ThreadB b = new ThreadB(service);
14         b.setName("B");
15 
16         ThreadC c = new ThreadC(service);
17         c.setName("C");
18 
19         a.start();
20         b.start();
21         c.start();
22     }
23 
24 }

  Phaser phaser = new Phaser(2);这里将参数设置成2(设置了2个parties),即等待两个线程同时到阻塞点后,再继续进行后面的程序,如果线程的数量大于参数的数量,则是两两为一组,到达阻塞点后再继续进行后序程序。

  而这里设置了3个线程,所以,只有其中的两个线程可以组合成功后继续下面的程序,而另外那个一个线程,将会被堵到阻塞点这里

 

2.arriveAndAwaitDeregister()方法

  如果Phaser phaser = new Phaser(3),这里设置了3个parties,此时正有3个线程运行,倘若中途有一个线程退出,那么其他两个线程将会被永远堵在阻塞点处,此时,使用arriveAndAwaitDeregister()方法,那么带来的效果就是parties会执行减1的操作,此时,堵在阻塞点的那辆线程就可以继续往下执行。

 1 package Three_Phaser_arriveAndDeregister;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Service {
 6 
 7     Phaser phaser;
 8 
 9     public Service(Phaser phaser) {
10         super();
11         this.phaser = phaser;
12     }
13 
14     public void methodA() throws InterruptedException {
15         System.out.println(Thread.currentThread().getName() + "赛程1 开始!!" + System.currentTimeMillis());
16         phaser.arriveAndAwaitAdvance();
17         System.out.println(Thread.currentThread().getName() + "赛程1 结束!!" + System.currentTimeMillis());
18     
19         Thread.sleep(5000);
20         System.out.println(Thread.currentThread().getName() + "赛程2 开始!!" + System.currentTimeMillis());
21         phaser.arriveAndAwaitAdvance();
22         System.out.println(Thread.currentThread().getName() + "赛程2 结束!!" + System.currentTimeMillis());
23         
24     }
25     
26     
27 
28     public void methodC() throws InterruptedException {
29         System.out.println(Thread.currentThread().getName() + "赛程1 开始!!" + System.currentTimeMillis());
30         Thread.sleep(5000);
31         phaser.arriveAndAwaitAdvance();
32         System.out.println(Thread.currentThread().getName() + "赛程1 结束!!" + System.currentTimeMillis());
33         Thread.sleep(5000);
34         System.out.println(Thread.currentThread().getName()+"退出比赛!!!");
35         phaser.arriveAndDeregister();//使parties减1
36         /*
37         System.out.println(Thread.currentThread().getName() + "赛程2 开始!!" + System.currentTimeMillis());
38         Thread.sleep(5000);
39         phaser.arriveAndAwaitAdvance();
40         System.out.println(Thread.currentThread().getName() + "赛程2 结束!!" + System.currentTimeMillis());
41         */
42     }
43 
44 }

 

package Three_Phaser_arriveAndDeregister;

import java.util.concurrent.Phaser;

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    public void run() {
        try {
            service.methodA();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
-----------------------------------------------------------------------------------------
package Three_Phaser_arriveAndDeregister;

import java.util.concurrent.Phaser;

public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    public void run() {
        try {
            service.methodA();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
-----------------------------------------------------------------------------------------
package Three_Phaser_arriveAndDeregister;

import java.util.concurrent.Phaser;

public class ThreadC extends Thread {

    private Service service;

    public ThreadC(Service service) {
        super();
        this.service = service;
    }

    public void run() {
        try {
            service.methodC();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
 1 package Three_Phaser_arriveAndDeregister;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Run {
 6     public static void main(String[] args) {
 7         Phaser phaser = new Phaser(3);
 8         Service service = new Service(phaser);
 9 
10         ThreadA a = new ThreadA(service);
11         a.setName("A");
12 
13         ThreadB b = new ThreadB(service);
14         b.setName("B");
15 
16         ThreadC c = new ThreadC(service);
17         c.setName("C");
18 
19         a.start();
20         b.start();
21         c.start();
22     }
23 
24 }

运行结果:

  可以看到,虽然C线程中途退出,但是由于执行了arriveAndDeregister()方法,使得parties的数量由3减为2,所以,只需要凑够2个线程就可以越过阻塞点,结果表现为,其他两个线程越过阻塞点,顺利执行下面的程序。

3. arrive()方法

  使parties的值-1,同时getArrivedParties()的值即已使用parties的值+1,并且使线程越过当前屏障点(越过后如果使用getPhase()方法来获取越过屏障的值,会发现,越过屏障值+1),继续进行下面的代码

(1)

 1 package Tree_Phaser_arrive3;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Service {
 6     Phaser phaser;
 7 
 8     public Service(Phaser phaser) {
 9         super();
10         this.phaser = phaser;
11     }
12 
13     public void methodA() throws InterruptedException {
14         System.out.println(Thread.currentThread().getName() + "赛程1  开始" + System.currentTimeMillis());
15         Thread.sleep(3000);
16         phaser.arriveAndAwaitAdvance();
17         System.out.println(Thread.currentThread().getName() + "赛程1  结束" + System.currentTimeMillis());
18     }
19 
20     public void methodB() {
21         System.out.println(Thread.currentThread().getName() + "赛程1  开始" + System.currentTimeMillis());
22         phaser.arrive();
23         System.out.println(Thread.currentThread().getName() + "赛程1  结束" + System.currentTimeMillis());
24     }
25 }
 1 package Tree_Phaser_arrive3;
 2 
 3 public class ThreadA extends Thread {
 4 
 5     private Service s;
 6 
 7     public ThreadA(Service s) {
 8         super();
 9         this.s = s;
10     }
11 
12     public void run() {
13 
14         try {
15             s.methodA();
16         } catch (InterruptedException e) {
17             // TODO Auto-generated catch block
18             e.printStackTrace();
19         }
20     }
21 
22 }
23 -----------------------------------------------------------------------------------------
24 package Tree_Phaser_arrive3;
25 
26 public class ThreadB extends Thread {
27 
28     private Service s;
29 
30     public ThreadB(Service s) {
31         super();
32         this.s = s;
33     }
34 
35     public void run() {
36 
37         try {
38             s.methodA();
39         } catch (InterruptedException e) {
40             // TODO Auto-generated catch block
41             e.printStackTrace();
42         }
43     }
44 
45 }
46 -----------------------------------------------------------------------------------------
47 package Tree_Phaser_arrive3;
48 
49 public class ThreadC extends Thread {
50 
51     private Service s;
52 
53     public ThreadC(Service s) {
54         super();
55         this.s = s;
56     }
57 
58     public void run() {
59 
60         s.methodB();
61 
62     }
63 
64 }
 1 package Tree_Phaser_arrive3;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Run {
 6     public static void main(String[] args) {
 7         Phaser phaser = new Phaser(3);
 8         Service s = new Service(phaser);
 9 
10         ThreadA a = new ThreadA(s);
11         a.setName("A");
12         ThreadB b = new ThreadB(s);
13         b.setName("B");
14         ThreadC c = new ThreadC(s);
15         c.setName("C");
16         a.start();
17         b.start();
18         c.start();
19     }
20 
21 }

运行结果:

分析:

  这里总共设置了3个parties,而只有线程A和线程B的方法中使用了arriveAndAwaitAdvance()方法,分别使parties的数量减1,剩下1个parties,然后A、B就被堵在阻塞点了,而线程C中使用的是arrive()的方法,使用后线程C接着往下执行,parties的值减1此时partiesd的值为,然后线程A、B就可以越过屏障点,继续向下执行。

 

  如果这里将parties的值设为4,则A、B执行完arriveAndAwaitAdvance()方法后,parties的值为2,A、B就被堵在阻塞点,而C通过执行arrive()越过当前阻塞点,并使parties的值减了1,可是当前parties的值为1,所以还需要一个操作来将其减为0后A、B才可以通过当前阻塞点,所以带来的结果就是:C顺利通过阻塞点,而A、B任然被堵在阻塞点。

(2)

 1 package Three_Phaser_arrive;
 2 
 3 import java.util.concurrent.Phaser;
 4 /*
 5  * 全程没有执行arriveAndAwaitAdvance()方法!!!
 6  */
 7 public class Run {
 8     public static void main(String[] argd) {
 9         Phaser phaser = new Phaser(2) {
10             protected boolean onAdvance(int phase, int registeredParties) {
11                 System.out.println("onAdvance()方法被调用");
12                 return false;
13             }
14         };
15 
16         System.out.println("A1 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
17                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
18         
19         phaser.arrive();//使parties的值+1,并且越过当前屏障(这时会使得getPhase的值+1,即越过的屏障数+1)向下面运行
20         
21         System.out.println("A1 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
22                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
23         
24         System.out.println("A2 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
25                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
26         
27         phaser.arrive();//使parties的值+1,并且越过当前屏障,向下面运行
28         
29         System.out.println("A2 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
30                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
31         
32         //////////////////////////////////////////////////
33         System.out.println("B1 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
34                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
35         
36         phaser.arrive();//使parties的值+1,并且越过当前屏障,向下面运行
37         
38         System.out.println("B1 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
39                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
40         
41         System.out.println("B2 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
42                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
43         
44         phaser.arrive();//使parties的值+1,并且越过当前屏障,向下面运行
45         
46         System.out.println("B2 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
47                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
48         
49         
50         ////////////////////////////////////////////////////
51         System.out.println("C1 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
52                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
53         
54         phaser.arrive();//使parties的值+1,并且越过当前屏障,向下面运行
55         
56         System.out.println("C1 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
57                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
58         
59         System.out.println("C2 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
60                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
61         
62         phaser.arrive();//使parties的值+1,并且越过当前屏障,向下面运行
63         
64         System.out.println("C2 getPhase(越过的屏障): " + phaser.getPhase() + "   getRegisteredParties(注册的parties数量): "
65                 + phaser.getRegisteredParties() + "   getArrivedParties(已经使用的parties数量): " + phaser.getArrivedParties());
66         
67         
68         
69     }
70 
71 }

运行结果:

   代码中没有写arriveAndAwaitAdvance()方法,所以说,这里没有通过之前的互相等待的方式,即让与parties值数量相同的线程执行arriveAndAwaitAdvance()方法,达到消除当前屏障,共同越过屏障的效果。

  这里使用arrive()方法,使得当前线程越过屏障,而这种arrive()方法带来的效果对于getPhase()的值和onAdvance()的行为的影响和之前使用arriveAndAwaitAdvance()方法是一样的。即:使用arrive()方法越过屏障和使用arriveAndAwaitAdvance()使parties的值减为0然后越过屏障,都会被认为是成功越过当前屏障,都会使得getPhase()的值增加;使用两者越过屏障后都会触发onAdvance()方法的执行。

  

4. awaitAdvance(int phase)方法

  传入参数phase的值和当前getPhase()方法返回值相同时,调用这个方法的线程将在阻塞点处等待,否则继续进行下面的程序。

 1 package Three_Phaser_awaitAdvance;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class ThreadA extends Thread {
 6 
 7     private Phaser phaser;
 8 
 9     public ThreadA(Phaser phaser) {
10         super();
11         this.phaser = phaser;
12     }
13 
14     public void run() {
15         System.out.println(Thread.currentThread().getName() + "A1 begin" + System.currentTimeMillis());
16         phaser.arriveAndAwaitAdvance();
17         System.out.println(Thread.currentThread().getName() + "A1 end" + System.currentTimeMillis());
18     }
19 }
20 --------------------------------------------------------------------------------------------
21 package Three_Phaser_awaitAdvance;
22 
23 import java.util.concurrent.Phaser;
24 
25 public class ThreadB extends Thread {
26 
27     private Phaser phaser;
28 
29     public ThreadB(Phaser phaser) {
30         super();
31         this.phaser = phaser;
32     }
33 
34     public void run() {
35         System.out.println(Thread.currentThread().getName() + "A1 begin" + System.currentTimeMillis());
36         phaser.arriveAndAwaitAdvance();
37         System.out.println(Thread.currentThread().getName() + "A1 end" + System.currentTimeMillis());
38     }
39 }
40 -----------------------------------------------------------------------------------------
41 package Three_Phaser_awaitAdvance;
42 
43 import java.util.concurrent.Phaser;
44 
45 public class ThreadC extends Thread {
46 
47     private Phaser phaser;
48 
49     public ThreadC(Phaser phaser) {
50         super();
51         this.phaser = phaser;
52     }
53 
54     public void run() {
55         try {
56             Thread.sleep(2000);
57         } catch (InterruptedException e) {
58             // TODO Auto-generated catch block
59             e.printStackTrace();
60         }
61         System.out.println(Thread.currentThread().getName() + "A1 begin" + System.currentTimeMillis());
62         System.out.println("已经越过的阻塞点个数: " + phaser.getPhase());
63         phaser.awaitAdvance(0);
64         System.out.println(Thread.currentThread().getName() + "A1 end" + System.currentTimeMillis());
65     }
66 }
67 -----------------------------------------------------------------------------------------
68 package Three_Phaser_awaitAdvance;
69 
70 import java.util.concurrent.Phaser;
71 
72 public class ThreadD extends Thread {
73 
74     private Phaser phaser;
75 
76     public ThreadD(Phaser phaser) {
77         super();
78         this.phaser = phaser;
79     }
80 
81     public void run() {
82         try {
83             Thread.sleep(5000);
84         } catch (InterruptedException e) {
85             // TODO Auto-generated catch block
86             e.printStackTrace();
87         }
88         System.out.println(Thread.currentThread().getName() + "A1 begin" + System.currentTimeMillis());
89         phaser.arriveAndAwaitAdvance();
90         System.out.println(Thread.currentThread().getName() + "A1 end" + System.currentTimeMillis());
91     }
92 }
 1 package Three_Phaser_awaitAdvance;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Run {
 6     public static void main(String[] args) {
 7         Phaser phaser = new Phaser(3);
 8 
 9         ThreadA a = new ThreadA(phaser);
10         a.setName("A");
11 
12         ThreadB b = new ThreadB(phaser);
13         b.setName("B");
14 
15         ThreadC c = new ThreadC(phaser);
16         c.setName("C");
17 
18         ThreadD d = new ThreadD(phaser);
19         d.setName("D");
20 
21         a.start();
22         b.start();
23         c.start();
24         d.start();
25     }
26 
27 }

运行结果:

分析:

  当前设置的参数为0,可以看到,在C线程中,通过getPhase()返回的值为0,与awaitAdvance(0)中传入的参数相同,此时线程C进入等待,而线程A、B还没有越过阻塞点,这也就是getPhase()返回值为0的原因,当D线程执行arriveAndAwaitAdvance()方法,将praties的值减为0时,A、B、D同时越过阻塞点,这个时候越过阻塞点的线程的数目为3,即此时getPhase()返回值为3,与awaitAdvance(0)中传入的参数0不同,此时线程C继续向下执行。

  如将参数改为3,即awaitAdvance(3),则C线程将先越过阻塞点继续执行

 1 package Three_Phaser_awaitAdvance;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class ThreadC extends Thread {
 6 
 7     private Phaser phaser;
 8 
 9     public ThreadC(Phaser phaser) {
10         super();
11         this.phaser = phaser;
12     }
13 
14     public void run() {
15         try {
16             Thread.sleep(2000);
17         } catch (InterruptedException e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }
21         System.out.println(Thread.currentThread().getName() + "A1 begin" + System.currentTimeMillis());
22         System.out.println("已经越过的阻塞点个数: " + phaser.getPhase());
23         phaser.awaitAdvance(3);//将传入的参数由0改为3
24         System.out.println(Thread.currentThread().getName() + "A1 end" + System.currentTimeMillis());
25     }
26 }

运行结果:

注:awaitAdvance(int Phase)并不参与parties计数操作,仅仅具有判断的功能。

(3)awaitAdvance(int Phase)在等待的时候,即当getPhase()的返回值与awaitAdvance(int Phase)中传递的参数不同时,线程处于等待状态中,这个时候如果有中断的话,线程状态不受影响,依旧会处于等待中。即不可中断

 

 1 package Three_Phaser_awaitAdvance2;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class MyThread extends Thread{
 6     private Phaser phaser;
 7 
 8     public MyThread(Phaser phaser) {
 9         super();
10         this.phaser = phaser;
11     }
12     
13     public void run(){
14         System.out.println(Thread.currentThread().getName()+" begin"+System.currentTimeMillis());
15         phaser.awaitAdvance(0);
16         System.out.println(Thread.currentThread().getName()+" end"+System.currentTimeMillis());
17         
18     }
19     
20 
21 }

 

 1 package Three_Phaser_awaitAdvance2;
 2 
 3 import java.util.concurrent.Phaser;
 4 
 5 public class Run {
 6     public static void main(String[] args) throws InterruptedException{
 7         Phaser phaser=new Phaser(3);
 8         MyThread mt=new MyThread(phaser);
 9         mt.setName("A");
10         mt.start();
11         Thread.sleep(5000);
12         mt.interrupt();//产生一个中断
13         System.out.println("中断");
14     }
15 
16 }

运行结果:

分析:

  可以看到,中断并没有影响线程A的继续等待,即虽然来了一个中断,但是线程A还是停在awaitAdvance(0)那里。

(4)awaitAdvanceInterruptibly(int Phaser)

  这个方法是可中断的,即,当线程停在awaitAdvanceInterruptibly(int Phaser)时,若进来一个中断,则线程就会被中断。

 

posted @ 2021-03-28 14:57  L1998  阅读(128)  评论(0)    收藏  举报