Enforce printing sequence but threads waiting on each other after one iteration











up vote
2
down vote

favorite












I am having trouble resolving this one thread waiting on another issue (even after viewing several questions posts). Here is what I am trying to do: I want one thread (called sub-thread) to print 10 times under outer-loop with 2 iterations; then another (boss-thread) to print 100 times under outer-loop with 2 iterations provided that sub-thread goes first. It will look something like this:



Sub Thread- iter = 1
Sub Thread- iter = 2
...
Sub Thread- iter = 10
Boss Thread- iter = 1
Boss Thread- iter = 2
...
Boss Thread- iter = 100


This sub-thread and boss-thread printing sequence will continue for 2 times (outer-loop).
My implementation has unpredicatable results, i.e. it prints out first iteration of sub-thread 10 times then halts there or it rarely prints out all statements and run through both the inner-loop and outer-loop. I use wait() and notify() to enable communication bewteen threads. I am not sure if I place synchronized block in the wrong place or I just mis-used the wait() and notify() pairs. Here's the code:



public class Main {

public static void main(String args) {
Main ic = new Main();

Thread t1 = new Thread(ic.new Th1(), "Boss Thread-");
Thread t2 = new Thread(ic.new Th2(), "Sub Thread-");

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

// Boss Thread
private class Th1 implements Runnable {

@Override
public void run() {
System.out.println("TH1 RUNS FIRST");
synchronized (Main.class) { // lock outside of outer loop so
// boss thread can pick up the next iteration
for (int i = 0; i < 2; i++) {
// wait, let the sub-thread run first
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

// print iterations
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}
System.out.println("end of boss outer----------------------" + (i + 1));
// wake up sub-thread and let it knows inner-iteration finished
Main.class.notify();
}
}
}
}

// Sub Thread
private class Th2 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (Main.class) { // lock up Th2
// print iterations
for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}

// wake up other boss thread and let it know inner-iteration finished
Main.class.notify();

// wait for other thread to run
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end of Sub outer---------------------- " + (i + 1));
}
}
}
}
}


Extra assistance needed: would someone tell me if synchronized is a good way of locking shared resource or other better alternatives are out there? Say ReentrantLock? Also, are notify() and wait() a good means to implement inter-threads communication or there are better means to make this less error-prone and more efficient?










share|improve this question
























  • please post your code directly in your question to avoid relying on external sources that may disappear in the future
    – njzk2
    Nov 10 at 5:15










  • @njzk2 As per requested, I posted the code in the description. Thanks.
    – Learner80239
    Nov 10 at 6:03










  • There are 2 issues I can see in your code: 1st is that you have no way of guaranteeing which thread acquires the lock on Main.class first. 2nd is that when you call notify, you are still holding the lock (as in the doc, "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.") although that part should be fine as there is a wait right after.
    – njzk2
    Nov 10 at 7:35










  • @njzk2 I'm not sure about "guaranteeing" a thread owning a lock. Are you suggesting using Lock or there is a way to enforce that along with synchronized? Also, thanks for pointing "holding the lock when invoking notify(). But I have to use notify() under some kind of synchronized block since it's only used if it owns a shared object (monitor), right?
    – Learner80239
    Nov 10 at 8:42

















up vote
2
down vote

favorite












I am having trouble resolving this one thread waiting on another issue (even after viewing several questions posts). Here is what I am trying to do: I want one thread (called sub-thread) to print 10 times under outer-loop with 2 iterations; then another (boss-thread) to print 100 times under outer-loop with 2 iterations provided that sub-thread goes first. It will look something like this:



Sub Thread- iter = 1
Sub Thread- iter = 2
...
Sub Thread- iter = 10
Boss Thread- iter = 1
Boss Thread- iter = 2
...
Boss Thread- iter = 100


This sub-thread and boss-thread printing sequence will continue for 2 times (outer-loop).
My implementation has unpredicatable results, i.e. it prints out first iteration of sub-thread 10 times then halts there or it rarely prints out all statements and run through both the inner-loop and outer-loop. I use wait() and notify() to enable communication bewteen threads. I am not sure if I place synchronized block in the wrong place or I just mis-used the wait() and notify() pairs. Here's the code:



public class Main {

public static void main(String args) {
Main ic = new Main();

Thread t1 = new Thread(ic.new Th1(), "Boss Thread-");
Thread t2 = new Thread(ic.new Th2(), "Sub Thread-");

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

// Boss Thread
private class Th1 implements Runnable {

@Override
public void run() {
System.out.println("TH1 RUNS FIRST");
synchronized (Main.class) { // lock outside of outer loop so
// boss thread can pick up the next iteration
for (int i = 0; i < 2; i++) {
// wait, let the sub-thread run first
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

// print iterations
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}
System.out.println("end of boss outer----------------------" + (i + 1));
// wake up sub-thread and let it knows inner-iteration finished
Main.class.notify();
}
}
}
}

// Sub Thread
private class Th2 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (Main.class) { // lock up Th2
// print iterations
for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}

// wake up other boss thread and let it know inner-iteration finished
Main.class.notify();

// wait for other thread to run
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end of Sub outer---------------------- " + (i + 1));
}
}
}
}
}


Extra assistance needed: would someone tell me if synchronized is a good way of locking shared resource or other better alternatives are out there? Say ReentrantLock? Also, are notify() and wait() a good means to implement inter-threads communication or there are better means to make this less error-prone and more efficient?










share|improve this question
























  • please post your code directly in your question to avoid relying on external sources that may disappear in the future
    – njzk2
    Nov 10 at 5:15










  • @njzk2 As per requested, I posted the code in the description. Thanks.
    – Learner80239
    Nov 10 at 6:03










  • There are 2 issues I can see in your code: 1st is that you have no way of guaranteeing which thread acquires the lock on Main.class first. 2nd is that when you call notify, you are still holding the lock (as in the doc, "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.") although that part should be fine as there is a wait right after.
    – njzk2
    Nov 10 at 7:35










  • @njzk2 I'm not sure about "guaranteeing" a thread owning a lock. Are you suggesting using Lock or there is a way to enforce that along with synchronized? Also, thanks for pointing "holding the lock when invoking notify(). But I have to use notify() under some kind of synchronized block since it's only used if it owns a shared object (monitor), right?
    – Learner80239
    Nov 10 at 8:42















up vote
2
down vote

favorite









up vote
2
down vote

favorite











I am having trouble resolving this one thread waiting on another issue (even after viewing several questions posts). Here is what I am trying to do: I want one thread (called sub-thread) to print 10 times under outer-loop with 2 iterations; then another (boss-thread) to print 100 times under outer-loop with 2 iterations provided that sub-thread goes first. It will look something like this:



Sub Thread- iter = 1
Sub Thread- iter = 2
...
Sub Thread- iter = 10
Boss Thread- iter = 1
Boss Thread- iter = 2
...
Boss Thread- iter = 100


This sub-thread and boss-thread printing sequence will continue for 2 times (outer-loop).
My implementation has unpredicatable results, i.e. it prints out first iteration of sub-thread 10 times then halts there or it rarely prints out all statements and run through both the inner-loop and outer-loop. I use wait() and notify() to enable communication bewteen threads. I am not sure if I place synchronized block in the wrong place or I just mis-used the wait() and notify() pairs. Here's the code:



public class Main {

public static void main(String args) {
Main ic = new Main();

Thread t1 = new Thread(ic.new Th1(), "Boss Thread-");
Thread t2 = new Thread(ic.new Th2(), "Sub Thread-");

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

// Boss Thread
private class Th1 implements Runnable {

@Override
public void run() {
System.out.println("TH1 RUNS FIRST");
synchronized (Main.class) { // lock outside of outer loop so
// boss thread can pick up the next iteration
for (int i = 0; i < 2; i++) {
// wait, let the sub-thread run first
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

// print iterations
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}
System.out.println("end of boss outer----------------------" + (i + 1));
// wake up sub-thread and let it knows inner-iteration finished
Main.class.notify();
}
}
}
}

// Sub Thread
private class Th2 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (Main.class) { // lock up Th2
// print iterations
for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}

// wake up other boss thread and let it know inner-iteration finished
Main.class.notify();

// wait for other thread to run
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end of Sub outer---------------------- " + (i + 1));
}
}
}
}
}


Extra assistance needed: would someone tell me if synchronized is a good way of locking shared resource or other better alternatives are out there? Say ReentrantLock? Also, are notify() and wait() a good means to implement inter-threads communication or there are better means to make this less error-prone and more efficient?










share|improve this question















I am having trouble resolving this one thread waiting on another issue (even after viewing several questions posts). Here is what I am trying to do: I want one thread (called sub-thread) to print 10 times under outer-loop with 2 iterations; then another (boss-thread) to print 100 times under outer-loop with 2 iterations provided that sub-thread goes first. It will look something like this:



Sub Thread- iter = 1
Sub Thread- iter = 2
...
Sub Thread- iter = 10
Boss Thread- iter = 1
Boss Thread- iter = 2
...
Boss Thread- iter = 100


This sub-thread and boss-thread printing sequence will continue for 2 times (outer-loop).
My implementation has unpredicatable results, i.e. it prints out first iteration of sub-thread 10 times then halts there or it rarely prints out all statements and run through both the inner-loop and outer-loop. I use wait() and notify() to enable communication bewteen threads. I am not sure if I place synchronized block in the wrong place or I just mis-used the wait() and notify() pairs. Here's the code:



public class Main {

public static void main(String args) {
Main ic = new Main();

Thread t1 = new Thread(ic.new Th1(), "Boss Thread-");
Thread t2 = new Thread(ic.new Th2(), "Sub Thread-");

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

// Boss Thread
private class Th1 implements Runnable {

@Override
public void run() {
System.out.println("TH1 RUNS FIRST");
synchronized (Main.class) { // lock outside of outer loop so
// boss thread can pick up the next iteration
for (int i = 0; i < 2; i++) {
// wait, let the sub-thread run first
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

// print iterations
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}
System.out.println("end of boss outer----------------------" + (i + 1));
// wake up sub-thread and let it knows inner-iteration finished
Main.class.notify();
}
}
}
}

// Sub Thread
private class Th2 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (Main.class) { // lock up Th2
// print iterations
for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + " iter = " + (j + 1));
}

// wake up other boss thread and let it know inner-iteration finished
Main.class.notify();

// wait for other thread to run
try {
Main.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end of Sub outer---------------------- " + (i + 1));
}
}
}
}
}


Extra assistance needed: would someone tell me if synchronized is a good way of locking shared resource or other better alternatives are out there? Say ReentrantLock? Also, are notify() and wait() a good means to implement inter-threads communication or there are better means to make this less error-prone and more efficient?







java multithreading wait notify






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 5:59

























asked Nov 10 at 4:10









Learner80239

113




113












  • please post your code directly in your question to avoid relying on external sources that may disappear in the future
    – njzk2
    Nov 10 at 5:15










  • @njzk2 As per requested, I posted the code in the description. Thanks.
    – Learner80239
    Nov 10 at 6:03










  • There are 2 issues I can see in your code: 1st is that you have no way of guaranteeing which thread acquires the lock on Main.class first. 2nd is that when you call notify, you are still holding the lock (as in the doc, "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.") although that part should be fine as there is a wait right after.
    – njzk2
    Nov 10 at 7:35










  • @njzk2 I'm not sure about "guaranteeing" a thread owning a lock. Are you suggesting using Lock or there is a way to enforce that along with synchronized? Also, thanks for pointing "holding the lock when invoking notify(). But I have to use notify() under some kind of synchronized block since it's only used if it owns a shared object (monitor), right?
    – Learner80239
    Nov 10 at 8:42




















  • please post your code directly in your question to avoid relying on external sources that may disappear in the future
    – njzk2
    Nov 10 at 5:15










  • @njzk2 As per requested, I posted the code in the description. Thanks.
    – Learner80239
    Nov 10 at 6:03










  • There are 2 issues I can see in your code: 1st is that you have no way of guaranteeing which thread acquires the lock on Main.class first. 2nd is that when you call notify, you are still holding the lock (as in the doc, "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.") although that part should be fine as there is a wait right after.
    – njzk2
    Nov 10 at 7:35










  • @njzk2 I'm not sure about "guaranteeing" a thread owning a lock. Are you suggesting using Lock or there is a way to enforce that along with synchronized? Also, thanks for pointing "holding the lock when invoking notify(). But I have to use notify() under some kind of synchronized block since it's only used if it owns a shared object (monitor), right?
    – Learner80239
    Nov 10 at 8:42


















please post your code directly in your question to avoid relying on external sources that may disappear in the future
– njzk2
Nov 10 at 5:15




please post your code directly in your question to avoid relying on external sources that may disappear in the future
– njzk2
Nov 10 at 5:15












@njzk2 As per requested, I posted the code in the description. Thanks.
– Learner80239
Nov 10 at 6:03




@njzk2 As per requested, I posted the code in the description. Thanks.
– Learner80239
Nov 10 at 6:03












There are 2 issues I can see in your code: 1st is that you have no way of guaranteeing which thread acquires the lock on Main.class first. 2nd is that when you call notify, you are still holding the lock (as in the doc, "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.") although that part should be fine as there is a wait right after.
– njzk2
Nov 10 at 7:35




There are 2 issues I can see in your code: 1st is that you have no way of guaranteeing which thread acquires the lock on Main.class first. 2nd is that when you call notify, you are still holding the lock (as in the doc, "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.") although that part should be fine as there is a wait right after.
– njzk2
Nov 10 at 7:35












@njzk2 I'm not sure about "guaranteeing" a thread owning a lock. Are you suggesting using Lock or there is a way to enforce that along with synchronized? Also, thanks for pointing "holding the lock when invoking notify(). But I have to use notify() under some kind of synchronized block since it's only used if it owns a shared object (monitor), right?
– Learner80239
Nov 10 at 8:42






@njzk2 I'm not sure about "guaranteeing" a thread owning a lock. Are you suggesting using Lock or there is a way to enforce that along with synchronized? Also, thanks for pointing "holding the lock when invoking notify(). But I have to use notify() under some kind of synchronized block since it's only used if it owns a shared object (monitor), right?
– Learner80239
Nov 10 at 8:42














1 Answer
1






active

oldest

votes

















up vote
0
down vote













After some thoughts and efforts, I've come up with an "implementation" that "meets" my expectation as described in the question post. I have made some changes to the wait and notify pairs and added an isTh2RunFirst flag to assist the communication of the two threads. Here's the code:



public class InterThCom {
// flag default to false for checking if sub-thread
// gets the lock first
private boolean isTh2RunFirst = false;

public static void main(String args) {
InterThCom itc = new InterThCom();

Thread t1 = new Thread(itc.new Th1(), "Boss-thread-");
Thread t2 = new Thread(itc.new Th2(), "Sub-thread-");

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

private class Th1 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (InterThCom.class) { // lock up inner-loop

// boss-thread gets the lock first
// wait for sub-thread and let it run;
// otherwise, skip this check
if (isTh2RunFirst == false) {
// wait for sub-thread, if boss-thread gets the lock first
try {
InterThCom.class.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}

// print iteration 100 times
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
}
// done printing 100 times

// sub-thread should run already at this point
isTh2RunFirst = true;

// This print helps split boss-th and sub-th prints
System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

// wake up sub-thread
InterThCom.class.notify();

// wait for sub-thread
try {
InterThCom.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

private class Th2 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (InterThCom.class) {
// print iteration 10 times
for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
}
// done printing 10 times

// sub-thread already prints j iteration
isTh2RunFirst = true;

// This print helps split boss-th and sub-th prints
System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

// wake up boss-thread
InterThCom.class.notify();

// wait for boss-thread
try {
InterThCom.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (InterThCom.class) {
// boss-thread is waiting at the last iteration, so wake it up
InterThCom.class.notify();
}
}
}

}


I also posted a Code Review post if anyone feels like addressing to "proper" implementation (in terms of industry practices and efficiency) of thread-communication in detail for this specific case or others in general.






share|improve this answer























    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',
    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%2f53235919%2fenforce-printing-sequence-but-threads-waiting-on-each-other-after-one-iteration%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








    up vote
    0
    down vote













    After some thoughts and efforts, I've come up with an "implementation" that "meets" my expectation as described in the question post. I have made some changes to the wait and notify pairs and added an isTh2RunFirst flag to assist the communication of the two threads. Here's the code:



    public class InterThCom {
    // flag default to false for checking if sub-thread
    // gets the lock first
    private boolean isTh2RunFirst = false;

    public static void main(String args) {
    InterThCom itc = new InterThCom();

    Thread t1 = new Thread(itc.new Th1(), "Boss-thread-");
    Thread t2 = new Thread(itc.new Th2(), "Sub-thread-");

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

    private class Th1 implements Runnable {

    @Override
    public void run() {
    for (int i = 0; i < 2; i++) {
    synchronized (InterThCom.class) { // lock up inner-loop

    // boss-thread gets the lock first
    // wait for sub-thread and let it run;
    // otherwise, skip this check
    if (isTh2RunFirst == false) {
    // wait for sub-thread, if boss-thread gets the lock first
    try {
    InterThCom.class.wait();
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }
    }

    // print iteration 100 times
    for (int j = 0; j < 100; j++) {
    System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
    }
    // done printing 100 times

    // sub-thread should run already at this point
    isTh2RunFirst = true;

    // This print helps split boss-th and sub-th prints
    System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

    // wake up sub-thread
    InterThCom.class.notify();

    // wait for sub-thread
    try {
    InterThCom.class.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }

    private class Th2 implements Runnable {

    @Override
    public void run() {
    for (int i = 0; i < 2; i++) {
    synchronized (InterThCom.class) {
    // print iteration 10 times
    for (int j = 0; j < 10; j++) {
    System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
    }
    // done printing 10 times

    // sub-thread already prints j iteration
    isTh2RunFirst = true;

    // This print helps split boss-th and sub-th prints
    System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

    // wake up boss-thread
    InterThCom.class.notify();

    // wait for boss-thread
    try {
    InterThCom.class.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    synchronized (InterThCom.class) {
    // boss-thread is waiting at the last iteration, so wake it up
    InterThCom.class.notify();
    }
    }
    }

    }


    I also posted a Code Review post if anyone feels like addressing to "proper" implementation (in terms of industry practices and efficiency) of thread-communication in detail for this specific case or others in general.






    share|improve this answer



























      up vote
      0
      down vote













      After some thoughts and efforts, I've come up with an "implementation" that "meets" my expectation as described in the question post. I have made some changes to the wait and notify pairs and added an isTh2RunFirst flag to assist the communication of the two threads. Here's the code:



      public class InterThCom {
      // flag default to false for checking if sub-thread
      // gets the lock first
      private boolean isTh2RunFirst = false;

      public static void main(String args) {
      InterThCom itc = new InterThCom();

      Thread t1 = new Thread(itc.new Th1(), "Boss-thread-");
      Thread t2 = new Thread(itc.new Th2(), "Sub-thread-");

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

      private class Th1 implements Runnable {

      @Override
      public void run() {
      for (int i = 0; i < 2; i++) {
      synchronized (InterThCom.class) { // lock up inner-loop

      // boss-thread gets the lock first
      // wait for sub-thread and let it run;
      // otherwise, skip this check
      if (isTh2RunFirst == false) {
      // wait for sub-thread, if boss-thread gets the lock first
      try {
      InterThCom.class.wait();
      } catch (InterruptedException e1) {
      e1.printStackTrace();
      }
      }

      // print iteration 100 times
      for (int j = 0; j < 100; j++) {
      System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
      }
      // done printing 100 times

      // sub-thread should run already at this point
      isTh2RunFirst = true;

      // This print helps split boss-th and sub-th prints
      System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

      // wake up sub-thread
      InterThCom.class.notify();

      // wait for sub-thread
      try {
      InterThCom.class.wait();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }
      }
      }
      }

      private class Th2 implements Runnable {

      @Override
      public void run() {
      for (int i = 0; i < 2; i++) {
      synchronized (InterThCom.class) {
      // print iteration 10 times
      for (int j = 0; j < 10; j++) {
      System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
      }
      // done printing 10 times

      // sub-thread already prints j iteration
      isTh2RunFirst = true;

      // This print helps split boss-th and sub-th prints
      System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

      // wake up boss-thread
      InterThCom.class.notify();

      // wait for boss-thread
      try {
      InterThCom.class.wait();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }
      }
      synchronized (InterThCom.class) {
      // boss-thread is waiting at the last iteration, so wake it up
      InterThCom.class.notify();
      }
      }
      }

      }


      I also posted a Code Review post if anyone feels like addressing to "proper" implementation (in terms of industry practices and efficiency) of thread-communication in detail for this specific case or others in general.






      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        After some thoughts and efforts, I've come up with an "implementation" that "meets" my expectation as described in the question post. I have made some changes to the wait and notify pairs and added an isTh2RunFirst flag to assist the communication of the two threads. Here's the code:



        public class InterThCom {
        // flag default to false for checking if sub-thread
        // gets the lock first
        private boolean isTh2RunFirst = false;

        public static void main(String args) {
        InterThCom itc = new InterThCom();

        Thread t1 = new Thread(itc.new Th1(), "Boss-thread-");
        Thread t2 = new Thread(itc.new Th2(), "Sub-thread-");

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

        private class Th1 implements Runnable {

        @Override
        public void run() {
        for (int i = 0; i < 2; i++) {
        synchronized (InterThCom.class) { // lock up inner-loop

        // boss-thread gets the lock first
        // wait for sub-thread and let it run;
        // otherwise, skip this check
        if (isTh2RunFirst == false) {
        // wait for sub-thread, if boss-thread gets the lock first
        try {
        InterThCom.class.wait();
        } catch (InterruptedException e1) {
        e1.printStackTrace();
        }
        }

        // print iteration 100 times
        for (int j = 0; j < 100; j++) {
        System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
        }
        // done printing 100 times

        // sub-thread should run already at this point
        isTh2RunFirst = true;

        // This print helps split boss-th and sub-th prints
        System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

        // wake up sub-thread
        InterThCom.class.notify();

        // wait for sub-thread
        try {
        InterThCom.class.wait();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        }
        }
        }

        private class Th2 implements Runnable {

        @Override
        public void run() {
        for (int i = 0; i < 2; i++) {
        synchronized (InterThCom.class) {
        // print iteration 10 times
        for (int j = 0; j < 10; j++) {
        System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
        }
        // done printing 10 times

        // sub-thread already prints j iteration
        isTh2RunFirst = true;

        // This print helps split boss-th and sub-th prints
        System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

        // wake up boss-thread
        InterThCom.class.notify();

        // wait for boss-thread
        try {
        InterThCom.class.wait();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        }
        synchronized (InterThCom.class) {
        // boss-thread is waiting at the last iteration, so wake it up
        InterThCom.class.notify();
        }
        }
        }

        }


        I also posted a Code Review post if anyone feels like addressing to "proper" implementation (in terms of industry practices and efficiency) of thread-communication in detail for this specific case or others in general.






        share|improve this answer














        After some thoughts and efforts, I've come up with an "implementation" that "meets" my expectation as described in the question post. I have made some changes to the wait and notify pairs and added an isTh2RunFirst flag to assist the communication of the two threads. Here's the code:



        public class InterThCom {
        // flag default to false for checking if sub-thread
        // gets the lock first
        private boolean isTh2RunFirst = false;

        public static void main(String args) {
        InterThCom itc = new InterThCom();

        Thread t1 = new Thread(itc.new Th1(), "Boss-thread-");
        Thread t2 = new Thread(itc.new Th2(), "Sub-thread-");

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

        private class Th1 implements Runnable {

        @Override
        public void run() {
        for (int i = 0; i < 2; i++) {
        synchronized (InterThCom.class) { // lock up inner-loop

        // boss-thread gets the lock first
        // wait for sub-thread and let it run;
        // otherwise, skip this check
        if (isTh2RunFirst == false) {
        // wait for sub-thread, if boss-thread gets the lock first
        try {
        InterThCom.class.wait();
        } catch (InterruptedException e1) {
        e1.printStackTrace();
        }
        }

        // print iteration 100 times
        for (int j = 0; j < 100; j++) {
        System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
        }
        // done printing 100 times

        // sub-thread should run already at this point
        isTh2RunFirst = true;

        // This print helps split boss-th and sub-th prints
        System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

        // wake up sub-thread
        InterThCom.class.notify();

        // wait for sub-thread
        try {
        InterThCom.class.wait();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        }
        }
        }

        private class Th2 implements Runnable {

        @Override
        public void run() {
        for (int i = 0; i < 2; i++) {
        synchronized (InterThCom.class) {
        // print iteration 10 times
        for (int j = 0; j < 10; j++) {
        System.out.println(Thread.currentThread().getName() + " iter-" + (j + 1));
        }
        // done printing 10 times

        // sub-thread already prints j iteration
        isTh2RunFirst = true;

        // This print helps split boss-th and sub-th prints
        System.out.println(Thread.currentThread().getName() + " outer-loop iter:" + (i + 1));

        // wake up boss-thread
        InterThCom.class.notify();

        // wait for boss-thread
        try {
        InterThCom.class.wait();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        }
        synchronized (InterThCom.class) {
        // boss-thread is waiting at the last iteration, so wake it up
        InterThCom.class.notify();
        }
        }
        }

        }


        I also posted a Code Review post if anyone feels like addressing to "proper" implementation (in terms of industry practices and efficiency) of thread-communication in detail for this specific case or others in general.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 10 at 17:40

























        answered Nov 10 at 17:33









        Learner80239

        113




        113






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53235919%2fenforce-printing-sequence-but-threads-waiting-on-each-other-after-one-iteration%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

            Schultheiß

            Verwaltungsgliederung Dänemarks

            Liste der Kulturdenkmale in Wilsdruff