0

I want to print my odd even number in order 1 2 3 4 5 6. I think first notify call in odd-thread should unblock the even-thread wait() to print next even number but it is not the case. It is printing only "1"

class T1 extends Thread { private String[] s1; private boolean flag; public T1(String[] args, boolean flag) { this.flag = flag; this.s1 = args; } public synchronized void run() { for (int i = 0; i < s1.length; i++) { if(flag) { try { wait(); } catch (InterruptedException e) { System.out.println("exception"); } } System.out.println(s1[i]); notify(); flag = true; } } } public class TestThread { public static void main(String[] args) { String[] s1 = { "1", "3", "5" }; String[] s2 = { "2", "4", "6" }; Runnable odd = new T1(s1,false); Runnable even = new T1(s2,true); new Thread(even,"even-thread ").start(); new Thread(odd,"odd-thread ").start(); } } 
2
  • 3
    You have two Thread objects, they aren't signaling eachother, they are signaling themselves. Use a shared object. Never notify or wait on Thread instances. Commented Jun 6, 2016 at 21:52
  • Welcome to StackOverflow. Please visit the help center and especially read How to Ask. Have you stepped through your code in your IDE debugger? That is the place to start. Commented Jun 6, 2016 at 21:52

3 Answers 3

3

As others point out, the two threads use different monitors, they should use a shared object as a monitor.

However, even fixing that will not solve all your problems. As it is I also see opportunity for a missed signal. (One thread may call notify, when the other isn't waiting).

All in all you don't regard some of the guidelines that should be used for wait-notify.

From Java Concurrency in Practice :

When using condition waits (Object.wait or Condition.await):

  • Always have a condition predicate—some test of object state that must hold before proceeding;
  • Always test the condition predicate before calling wait, and again after returning from wait;
  • Always call wait in a loop;
  • Ensure that the state variables making up the condition predicate are guarded by the lock associated with the condition queue;
  • Hold the lock associated with the the condition queue when calling wait, notify, or notifyAll; and
  • Do not release the lock after checking the condition predicate but before acting on it.
Sign up to request clarification or add additional context in comments.

3 Comments

Another good resource, and one that the noobs can read for free, is the "Guarded Blocks" section in the Oracle Java tutorials: docs.oracle.com/javase/tutorial/essential/concurrency/…
@WarrenDew Consider this scheduling : The odd thread gets into the synchronized block first, calls notify (no threads waiting) and sets the flag to true, then enters its second loop, and starts waiting. Then the even thread can get into the synchronized block, flag is true so it also starts waiting. Yet it has missed the signal it should wait for. Now both threads are waiting for a signal that will never come.
You're correct, I was only looking at steady state and not at startup. Good point.
2

Your threads are notifying themselves rather than notifying the other thread.

You could fix this by notifying the other thread after synchronizing on its monitor. However, it would be better to wait() and notify() on a shared Object.

Comments

0

You may need the code like this:

class MyThread extends Thread { private Object object; private String[] s1; public MyThread(String[] args, Object object) { this.object = object; this.s1 = args; } public void run() { synchronized (object) { for (int i = 0; i < s1.length; i++) { System.out.println(s1[i]); object.notifyAll(); if (i == s1.length - 1) return; try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class TestThread { private static Object object = new Object(); public static void main(String[] args) { String[] s1 = { "1", "3", "5" }; String[] s2 = { "2", "4", "6" }; Thread odd = new MyThread(s1, object); odd.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } Thread even = new MyThread(s2, object); even.start(); } } 

the output is:

1 2 3 4 5 6 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.