I have the following Thread example:
class Q
{
int num;
public synchronized void put(int num) {
System.out.println("Put :"+num);
this.num = num;
try {Thread.sleep(100);} catch (Exception e) {}
notify();
try {wait();} catch (Exception e) {}
}
public synchronized void get() {
try {wait();} catch (Exception e) {}
System.out.println("Get :"+num);
notify();
}
}
class Producer implements Runnable
{
Q q;
public Producer(Q q) {
this.q = q;
Thread t = new Thread(this,"Producer");
t.start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
try {Thread.sleep(1000);} catch (Exception e) {}
}
}
}
class Consumer implements Runnable
{
Q q;
Thread t;
public Consumer(Q q) {
this.q = q;
t = new Thread(this,"Consumer");
t.start();
}
public void run() {
while(true) {
q.get();
try {Thread.sleep(500);} catch (Exception e) {}
}
}
}
public class InterThread {
public static void main(String[] args) {
Q q = new Q();
new Producer(q);
new Consumer(q);
}
}
I'm trying to run two threads, consumer and producer, in a loop.
sharing the same object q, one thread incrementing q.num and printing the value of it, and the other is consuming q.num by just printing its value.
The result I'm getting in a console is "Put :0" and stops there,
consumer thread not being called, even though I used Thread.sleep(100);
before calling notify() in the producer thread, why !!?
In this case, Producer thread is starting before Consumer. notify() is getting called, following by that wait() getting called. Producer thread goes in waiting state, releases acquired lock.
// producer
notify();
try {
System.out.println(Thread.currentThread().getName() + " Put :"+num);
this.wait(); // lock released
}
catch (Exception e) {
}
Now consumer thread acquires the lock, wait() is executed. Consumer
goes in the waiting state.
// consumer
try {
System.out.println(Thread.currentThread().getName() + "Get :"+num);
this.wait(); // Both the threads are waiting
}
catch (Exception e) {
}
Now both the threads are waiting for notify
call from the other thread
Note that Sleep()
method doesn't release the lock , so there is no point in calling calling Thread.sleep
before the producer's notify