Registering thread to Phaser












1















I am learning about Phaser. While doing so, I came across a problem. Below is the code that I have,



public class RunnableTask implements Runnable {

private Phaser phaser;

public RunnableTask(Phaser phaser) {
this.phaser = phaser;
this.phaser.register(); // Question
}

@Override
public void run() {
// this.phaser.register(); // Question
print("After register");
for (int i = 0; i < 2; i++) {
sleep();
print("Before await" + i + ":");
this.phaser.arriveAndAwaitAdvance();
print("After advance" + i + ":");
}
}

private void sleep() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void print(String msg) {

System.out.println(String.format("%s: %s, time=%s, registered=%s, arrived=%s, unarrived=%s, phase=%s.", msg,
Thread.currentThread().getName(), LocalTime.now(), this.phaser.getRegisteredParties(),
this.phaser.getArrivedParties(), this.phaser.getUnarrivedParties(), this.phaser.getPhase()));
}

}


Sample test for the above



public class TestPhaser {

public static void main(String args) {

Phaser phaser = new Phaser();

RunnableTask task = new RunnableTask(phaser);

Thread t1 = new Thread(task, "t1");
Thread t2 = new Thread(task, "t2");
Thread t3 = new Thread(task, "t3");

t1.start();
t2.start();
t3.start();
}
}


Upon executing the above program the output is :




After register: t3, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t2, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t1, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t3, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



After advance 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t3, time=22:01:28.729, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t3, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=4.



After advance 1:: t3, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=5.



Before await 1:: t1, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t1, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=6.




You can see there are lots of discrepancies here. The threads are not advanced in a sequence. Also, there are few phases missing or/and not in a sequence.



When I moved the line of code this.phaser.register() from constructor to the beginning of the run method, the output is :




After register: t1, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t3, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t2, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t2, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t1, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t3, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



After advance 0:: t2, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t3, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t1, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t1, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t2, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t3, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 1:: t3, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t2, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t1, time=22:11:02.321, registered=3, arrived=0,
unarrived=3, phase=2.




This looks much better that the threads execution and phases are in a sequence.



Here are my questions:



1) Why there are lots of discrepancies when parties were registered inside the constructor of Runnable?



2) In the second result, the stats for arrived and unarrived are zero (incorrect) at each phase. So, how to obtain the correct numbers for them?



Any help is appreciated.










share|improve this question

























  • Just wondering if that is the behavior of overridden run from the Runnable within which you've included a sleep that you're observing.

    – Naman
    Nov 26 '18 at 3:46













  • @nullpointer: I appreciate your willingness to help. it will be helpful if you could link to the section of javadoc that describes that behavior.

    – JohnySam
    Nov 26 '18 at 3:57


















1















I am learning about Phaser. While doing so, I came across a problem. Below is the code that I have,



public class RunnableTask implements Runnable {

private Phaser phaser;

public RunnableTask(Phaser phaser) {
this.phaser = phaser;
this.phaser.register(); // Question
}

@Override
public void run() {
// this.phaser.register(); // Question
print("After register");
for (int i = 0; i < 2; i++) {
sleep();
print("Before await" + i + ":");
this.phaser.arriveAndAwaitAdvance();
print("After advance" + i + ":");
}
}

private void sleep() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void print(String msg) {

System.out.println(String.format("%s: %s, time=%s, registered=%s, arrived=%s, unarrived=%s, phase=%s.", msg,
Thread.currentThread().getName(), LocalTime.now(), this.phaser.getRegisteredParties(),
this.phaser.getArrivedParties(), this.phaser.getUnarrivedParties(), this.phaser.getPhase()));
}

}


Sample test for the above



public class TestPhaser {

public static void main(String args) {

Phaser phaser = new Phaser();

RunnableTask task = new RunnableTask(phaser);

Thread t1 = new Thread(task, "t1");
Thread t2 = new Thread(task, "t2");
Thread t3 = new Thread(task, "t3");

t1.start();
t2.start();
t3.start();
}
}


Upon executing the above program the output is :




After register: t3, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t2, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t1, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t3, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



After advance 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t3, time=22:01:28.729, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t3, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=4.



After advance 1:: t3, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=5.



Before await 1:: t1, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t1, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=6.




You can see there are lots of discrepancies here. The threads are not advanced in a sequence. Also, there are few phases missing or/and not in a sequence.



When I moved the line of code this.phaser.register() from constructor to the beginning of the run method, the output is :




After register: t1, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t3, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t2, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t2, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t1, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t3, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



After advance 0:: t2, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t3, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t1, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t1, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t2, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t3, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 1:: t3, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t2, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t1, time=22:11:02.321, registered=3, arrived=0,
unarrived=3, phase=2.




This looks much better that the threads execution and phases are in a sequence.



Here are my questions:



1) Why there are lots of discrepancies when parties were registered inside the constructor of Runnable?



2) In the second result, the stats for arrived and unarrived are zero (incorrect) at each phase. So, how to obtain the correct numbers for them?



Any help is appreciated.










share|improve this question

























  • Just wondering if that is the behavior of overridden run from the Runnable within which you've included a sleep that you're observing.

    – Naman
    Nov 26 '18 at 3:46













  • @nullpointer: I appreciate your willingness to help. it will be helpful if you could link to the section of javadoc that describes that behavior.

    – JohnySam
    Nov 26 '18 at 3:57
















1












1








1








I am learning about Phaser. While doing so, I came across a problem. Below is the code that I have,



public class RunnableTask implements Runnable {

private Phaser phaser;

public RunnableTask(Phaser phaser) {
this.phaser = phaser;
this.phaser.register(); // Question
}

@Override
public void run() {
// this.phaser.register(); // Question
print("After register");
for (int i = 0; i < 2; i++) {
sleep();
print("Before await" + i + ":");
this.phaser.arriveAndAwaitAdvance();
print("After advance" + i + ":");
}
}

private void sleep() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void print(String msg) {

System.out.println(String.format("%s: %s, time=%s, registered=%s, arrived=%s, unarrived=%s, phase=%s.", msg,
Thread.currentThread().getName(), LocalTime.now(), this.phaser.getRegisteredParties(),
this.phaser.getArrivedParties(), this.phaser.getUnarrivedParties(), this.phaser.getPhase()));
}

}


Sample test for the above



public class TestPhaser {

public static void main(String args) {

Phaser phaser = new Phaser();

RunnableTask task = new RunnableTask(phaser);

Thread t1 = new Thread(task, "t1");
Thread t2 = new Thread(task, "t2");
Thread t3 = new Thread(task, "t3");

t1.start();
t2.start();
t3.start();
}
}


Upon executing the above program the output is :




After register: t3, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t2, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t1, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t3, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



After advance 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t3, time=22:01:28.729, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t3, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=4.



After advance 1:: t3, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=5.



Before await 1:: t1, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t1, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=6.




You can see there are lots of discrepancies here. The threads are not advanced in a sequence. Also, there are few phases missing or/and not in a sequence.



When I moved the line of code this.phaser.register() from constructor to the beginning of the run method, the output is :




After register: t1, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t3, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t2, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t2, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t1, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t3, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



After advance 0:: t2, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t3, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t1, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t1, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t2, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t3, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 1:: t3, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t2, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t1, time=22:11:02.321, registered=3, arrived=0,
unarrived=3, phase=2.




This looks much better that the threads execution and phases are in a sequence.



Here are my questions:



1) Why there are lots of discrepancies when parties were registered inside the constructor of Runnable?



2) In the second result, the stats for arrived and unarrived are zero (incorrect) at each phase. So, how to obtain the correct numbers for them?



Any help is appreciated.










share|improve this question
















I am learning about Phaser. While doing so, I came across a problem. Below is the code that I have,



public class RunnableTask implements Runnable {

private Phaser phaser;

public RunnableTask(Phaser phaser) {
this.phaser = phaser;
this.phaser.register(); // Question
}

@Override
public void run() {
// this.phaser.register(); // Question
print("After register");
for (int i = 0; i < 2; i++) {
sleep();
print("Before await" + i + ":");
this.phaser.arriveAndAwaitAdvance();
print("After advance" + i + ":");
}
}

private void sleep() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void print(String msg) {

System.out.println(String.format("%s: %s, time=%s, registered=%s, arrived=%s, unarrived=%s, phase=%s.", msg,
Thread.currentThread().getName(), LocalTime.now(), this.phaser.getRegisteredParties(),
this.phaser.getArrivedParties(), this.phaser.getUnarrivedParties(), this.phaser.getPhase()));
}

}


Sample test for the above



public class TestPhaser {

public static void main(String args) {

Phaser phaser = new Phaser();

RunnableTask task = new RunnableTask(phaser);

Thread t1 = new Thread(task, "t1");
Thread t2 = new Thread(task, "t2");
Thread t3 = new Thread(task, "t3");

t1.start();
t2.start();
t3.start();
}
}


Upon executing the above program the output is :




After register: t3, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t2, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



After register: t1, time=22:01:26.636, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t3, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



Before await 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=0.



After advance 0:: t1, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t2, time=22:01:28.728, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 0:: t3, time=22:01:28.729, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



Before await 1:: t3, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t2, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=4.



After advance 1:: t3, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=5.



Before await 1:: t1, time=22:01:30.730, registered=1, arrived=0,
unarrived=1, phase=3.



After advance 1:: t1, time=22:01:30.732, registered=1, arrived=0,
unarrived=1, phase=6.




You can see there are lots of discrepancies here. The threads are not advanced in a sequence. Also, there are few phases missing or/and not in a sequence.



When I moved the line of code this.phaser.register() from constructor to the beginning of the run method, the output is :




After register: t1, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t3, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



After register: t2, time=22:10:58.230, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t2, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t1, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



Before await 0:: t3, time=22:11:00.314, registered=3, arrived=0,
unarrived=3, phase=0.



After advance 0:: t2, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t3, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 0:: t1, time=22:11:00.315, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t1, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t2, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



Before await 1:: t3, time=22:11:02.319, registered=3, arrived=0,
unarrived=3, phase=1.



After advance 1:: t3, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t2, time=22:11:02.320, registered=3, arrived=0,
unarrived=3, phase=2.



After advance 1:: t1, time=22:11:02.321, registered=3, arrived=0,
unarrived=3, phase=2.




This looks much better that the threads execution and phases are in a sequence.



Here are my questions:



1) Why there are lots of discrepancies when parties were registered inside the constructor of Runnable?



2) In the second result, the stats for arrived and unarrived are zero (incorrect) at each phase. So, how to obtain the correct numbers for them?



Any help is appreciated.







java multithreading concurrency java.util.concurrent phaser






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 '18 at 3:44







JohnySam

















asked Nov 26 '18 at 3:19









JohnySamJohnySam

1052211




1052211













  • Just wondering if that is the behavior of overridden run from the Runnable within which you've included a sleep that you're observing.

    – Naman
    Nov 26 '18 at 3:46













  • @nullpointer: I appreciate your willingness to help. it will be helpful if you could link to the section of javadoc that describes that behavior.

    – JohnySam
    Nov 26 '18 at 3:57





















  • Just wondering if that is the behavior of overridden run from the Runnable within which you've included a sleep that you're observing.

    – Naman
    Nov 26 '18 at 3:46













  • @nullpointer: I appreciate your willingness to help. it will be helpful if you could link to the section of javadoc that describes that behavior.

    – JohnySam
    Nov 26 '18 at 3:57



















Just wondering if that is the behavior of overridden run from the Runnable within which you've included a sleep that you're observing.

– Naman
Nov 26 '18 at 3:46







Just wondering if that is the behavior of overridden run from the Runnable within which you've included a sleep that you're observing.

– Naman
Nov 26 '18 at 3:46















@nullpointer: I appreciate your willingness to help. it will be helpful if you could link to the section of javadoc that describes that behavior.

– JohnySam
Nov 26 '18 at 3:57







@nullpointer: I appreciate your willingness to help. it will be helpful if you could link to the section of javadoc that describes that behavior.

– JohnySam
Nov 26 '18 at 3:57














1 Answer
1






active

oldest

votes


















1














In first example "creation phaser in constructor", you are registering only one thread to Phaser. You have to create three tasks, to register three threads in phaser.



Change the code like this, and it will work.
(dont forget to remove initial RunnableTask task = new RunnableTask(phaser); from your code)



    Thread t1 = new Thread(new RunnableTask(phaser), "t1");
Thread t2 = new Thread(new RunnableTask(phaser), "t2");
Thread t3 = new Thread(new RunnableTask(phaser), "t3");


In second example, you wait exactly 2 seconds in all threads, this is to exact and all of them arrive and await almost at the same time, change your sleep method like this to introduce some different waits for the threads to see some arrived and unarrived threads



  private void sleep() {
try {
Random r = new Random();
TimeUnit.SECONDS.sleep(r.nextInt(5));
} catch(InterruptedException e) {
e.printStackTrace();
}
}


Your second example works but its not correct.It works only because you have sleep at the beginning of the run method so all threads catch up to register in phaser before you call arrive and advance method on phaser.
If you would remove the sleep then after calling this line



t1.start();


T1 run method will be run and t1 thread would be register in the phaser. Then is possible that the this.phaser.arriveAndAwaitAdvance() in t1 run method will be called before threads t2 and t3 are started and registrated in the phaser so the phaser will not wait for them.



You should register into phaser in constructor of the task, or in the method that is called before you start the thread.






share|improve this answer


























  • Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

    – JohnySam
    Nov 26 '18 at 13:28













  • I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

    – HPCS
    Nov 26 '18 at 14:11











  • I updated the last paragraph in the answer.

    – HPCS
    Nov 26 '18 at 14:18











  • Thanks and now it makes a lot of sense.

    – JohnySam
    Nov 26 '18 at 16:07













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53474375%2fregistering-thread-to-phaser%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














In first example "creation phaser in constructor", you are registering only one thread to Phaser. You have to create three tasks, to register three threads in phaser.



Change the code like this, and it will work.
(dont forget to remove initial RunnableTask task = new RunnableTask(phaser); from your code)



    Thread t1 = new Thread(new RunnableTask(phaser), "t1");
Thread t2 = new Thread(new RunnableTask(phaser), "t2");
Thread t3 = new Thread(new RunnableTask(phaser), "t3");


In second example, you wait exactly 2 seconds in all threads, this is to exact and all of them arrive and await almost at the same time, change your sleep method like this to introduce some different waits for the threads to see some arrived and unarrived threads



  private void sleep() {
try {
Random r = new Random();
TimeUnit.SECONDS.sleep(r.nextInt(5));
} catch(InterruptedException e) {
e.printStackTrace();
}
}


Your second example works but its not correct.It works only because you have sleep at the beginning of the run method so all threads catch up to register in phaser before you call arrive and advance method on phaser.
If you would remove the sleep then after calling this line



t1.start();


T1 run method will be run and t1 thread would be register in the phaser. Then is possible that the this.phaser.arriveAndAwaitAdvance() in t1 run method will be called before threads t2 and t3 are started and registrated in the phaser so the phaser will not wait for them.



You should register into phaser in constructor of the task, or in the method that is called before you start the thread.






share|improve this answer


























  • Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

    – JohnySam
    Nov 26 '18 at 13:28













  • I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

    – HPCS
    Nov 26 '18 at 14:11











  • I updated the last paragraph in the answer.

    – HPCS
    Nov 26 '18 at 14:18











  • Thanks and now it makes a lot of sense.

    – JohnySam
    Nov 26 '18 at 16:07


















1














In first example "creation phaser in constructor", you are registering only one thread to Phaser. You have to create three tasks, to register three threads in phaser.



Change the code like this, and it will work.
(dont forget to remove initial RunnableTask task = new RunnableTask(phaser); from your code)



    Thread t1 = new Thread(new RunnableTask(phaser), "t1");
Thread t2 = new Thread(new RunnableTask(phaser), "t2");
Thread t3 = new Thread(new RunnableTask(phaser), "t3");


In second example, you wait exactly 2 seconds in all threads, this is to exact and all of them arrive and await almost at the same time, change your sleep method like this to introduce some different waits for the threads to see some arrived and unarrived threads



  private void sleep() {
try {
Random r = new Random();
TimeUnit.SECONDS.sleep(r.nextInt(5));
} catch(InterruptedException e) {
e.printStackTrace();
}
}


Your second example works but its not correct.It works only because you have sleep at the beginning of the run method so all threads catch up to register in phaser before you call arrive and advance method on phaser.
If you would remove the sleep then after calling this line



t1.start();


T1 run method will be run and t1 thread would be register in the phaser. Then is possible that the this.phaser.arriveAndAwaitAdvance() in t1 run method will be called before threads t2 and t3 are started and registrated in the phaser so the phaser will not wait for them.



You should register into phaser in constructor of the task, or in the method that is called before you start the thread.






share|improve this answer


























  • Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

    – JohnySam
    Nov 26 '18 at 13:28













  • I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

    – HPCS
    Nov 26 '18 at 14:11











  • I updated the last paragraph in the answer.

    – HPCS
    Nov 26 '18 at 14:18











  • Thanks and now it makes a lot of sense.

    – JohnySam
    Nov 26 '18 at 16:07
















1












1








1







In first example "creation phaser in constructor", you are registering only one thread to Phaser. You have to create three tasks, to register three threads in phaser.



Change the code like this, and it will work.
(dont forget to remove initial RunnableTask task = new RunnableTask(phaser); from your code)



    Thread t1 = new Thread(new RunnableTask(phaser), "t1");
Thread t2 = new Thread(new RunnableTask(phaser), "t2");
Thread t3 = new Thread(new RunnableTask(phaser), "t3");


In second example, you wait exactly 2 seconds in all threads, this is to exact and all of them arrive and await almost at the same time, change your sleep method like this to introduce some different waits for the threads to see some arrived and unarrived threads



  private void sleep() {
try {
Random r = new Random();
TimeUnit.SECONDS.sleep(r.nextInt(5));
} catch(InterruptedException e) {
e.printStackTrace();
}
}


Your second example works but its not correct.It works only because you have sleep at the beginning of the run method so all threads catch up to register in phaser before you call arrive and advance method on phaser.
If you would remove the sleep then after calling this line



t1.start();


T1 run method will be run and t1 thread would be register in the phaser. Then is possible that the this.phaser.arriveAndAwaitAdvance() in t1 run method will be called before threads t2 and t3 are started and registrated in the phaser so the phaser will not wait for them.



You should register into phaser in constructor of the task, or in the method that is called before you start the thread.






share|improve this answer















In first example "creation phaser in constructor", you are registering only one thread to Phaser. You have to create three tasks, to register three threads in phaser.



Change the code like this, and it will work.
(dont forget to remove initial RunnableTask task = new RunnableTask(phaser); from your code)



    Thread t1 = new Thread(new RunnableTask(phaser), "t1");
Thread t2 = new Thread(new RunnableTask(phaser), "t2");
Thread t3 = new Thread(new RunnableTask(phaser), "t3");


In second example, you wait exactly 2 seconds in all threads, this is to exact and all of them arrive and await almost at the same time, change your sleep method like this to introduce some different waits for the threads to see some arrived and unarrived threads



  private void sleep() {
try {
Random r = new Random();
TimeUnit.SECONDS.sleep(r.nextInt(5));
} catch(InterruptedException e) {
e.printStackTrace();
}
}


Your second example works but its not correct.It works only because you have sleep at the beginning of the run method so all threads catch up to register in phaser before you call arrive and advance method on phaser.
If you would remove the sleep then after calling this line



t1.start();


T1 run method will be run and t1 thread would be register in the phaser. Then is possible that the this.phaser.arriveAndAwaitAdvance() in t1 run method will be called before threads t2 and t3 are started and registrated in the phaser so the phaser will not wait for them.



You should register into phaser in constructor of the task, or in the method that is called before you start the thread.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 26 '18 at 14:30

























answered Nov 26 '18 at 9:03









HPCSHPCS

728619




728619













  • Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

    – JohnySam
    Nov 26 '18 at 13:28













  • I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

    – HPCS
    Nov 26 '18 at 14:11











  • I updated the last paragraph in the answer.

    – HPCS
    Nov 26 '18 at 14:18











  • Thanks and now it makes a lot of sense.

    – JohnySam
    Nov 26 '18 at 16:07





















  • Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

    – JohnySam
    Nov 26 '18 at 13:28













  • I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

    – HPCS
    Nov 26 '18 at 14:11











  • I updated the last paragraph in the answer.

    – HPCS
    Nov 26 '18 at 14:18











  • Thanks and now it makes a lot of sense.

    – JohnySam
    Nov 26 '18 at 16:07



















Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

– JohnySam
Nov 26 '18 at 13:28







Thanks for the clarification. I agree to most part of your answer. However, I'm confused and couldn't understand the last paragraph wherein you said 'works but it's not correct'. What I undestood is, I should move the registration of parties to the constructor of the runnable and change the sleep time to random number for each party. Is this all you wanted to say or is there is something still left that I didnt understand?

– JohnySam
Nov 26 '18 at 13:28















I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

– HPCS
Nov 26 '18 at 14:11





I mean this. Its not correct because you register the thread in the phaser in the run method that is called when the thread start. If you remove the sleep, than after this line t1.start(); the t1-run method will register in phaser and immediatelly call this.phaser.arriveAndAwaitAdvance() and will not wait for other threads(T2,T3) , because only one thread has been registrated in phaser so far. The sleep method you use create the time for thread t2,and t3 to start and register in phaser.

– HPCS
Nov 26 '18 at 14:11













I updated the last paragraph in the answer.

– HPCS
Nov 26 '18 at 14:18





I updated the last paragraph in the answer.

– HPCS
Nov 26 '18 at 14:18













Thanks and now it makes a lot of sense.

– JohnySam
Nov 26 '18 at 16:07







Thanks and now it makes a lot of sense.

– JohnySam
Nov 26 '18 at 16:07






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53474375%2fregistering-thread-to-phaser%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen