Reputation: 11
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();
}
}
Upvotes: 0
Views: 85
Reputation: 96
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
Upvotes: 0
Reputation: 11280
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
orCondition.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 fromwait
;- 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
, ornotifyAll
; and- Do not release the lock after checking the condition predicate but before acting on it.
Upvotes: 3
Reputation: 8928
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
.
Upvotes: 2