Can't make one thread waiting for another while running

L

lonelyplanet999

Hi,

I'm writing a program to make one thread periodically notifying
another regularly.

I tried 2 approaches. Both caused the waiting thead t1 triggered below
runtime exception:

I would like to know what's wrong with the coding & any solution to
make the waiting happen :)

Approach 1
==========
public class Waiting6 {
public static void main (String [] args) {
System.out.println("Program starts");
MyThread2 t2 = new MyThread2();
MyThread1 t1 = new MyThread1(t2);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}

class MyThread1 extends Thread {
MyThread2 t2;
MyThread1 (MyThread2 t2) {
this.t2 = t2;
}
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running...");
synchronized(this) {
try {
t2.wait();
} catch(InterruptedException e) {}
}
}
}
}

class MyThread2 extends Thread {
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running***");
try {
System.out.println(name+" is sleeping...");
Thread.sleep(2000);
} catch(InterruptedException e) {}
synchronized(this) {
System.out.println(name+" will notify waiting thread...");
notify();
}
}
}
}

Runtime exception triggered
===========================
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:426)
at MyThread1.run(Waiting7.java:25)

Approach 2
==========
public class Waiting7 {
public static void main (String [] args) {
System.out.println("Program starts");
MyThread2 t2 = new MyThread2();
MyThread1 t1 = new MyThread1();
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}

class MyThread1 extends Thread {
MyThread2 t2 = new MyThread2();
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running...");
synchronized(this) {
try {
t2.wait();
} catch(InterruptedException e) {}
}
}
}
}

class MyThread2 extends Thread {
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running***");
try {
System.out.println(name+" is sleeping...");
Thread.sleep(2000);
} catch(InterruptedException e) {}
synchronized(this) {
System.out.println(name+" will notify waiting thread...");
notify();
}
}
}
}

Runtime exception triggered
===========================
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:426)
at MyThread1.run(Waiting7.java:25)
 
P

Peter J. Grey

Hi!
synchronized(this) {
try {
t2.wait();
} catch(InterruptedException e) {}
}

You're calling wait() on a different object from the one you acquired the
synchronization lock for.
Try synchronized(t2) instead of synchronized(this). The other approach is
the same problem with the locks the other way around.

You should probably try a dedicated lock object (new Object() will work),
rather than synchronizing on the thread objects - that may make the design
clearer.

Peter
 
L

lonelyplanet999

(e-mail address removed) (lonelyplanet999) wrote in message
I would like to ask is Thread class or it's subclass objects couldn't
use wait() method ?

i.e. a.wait() is not allowed if a is a Thread object instance or
object instance of Thread's subclass ?

Tks:)
Hi,

I'm writing a program to make one thread periodically notifying
another regularly.

I tried 2 approaches. Both caused the waiting thead t1 triggered below
runtime exception:

I would like to know what's wrong with the coding & any solution to
make the waiting happen :)

Approach 1
==========
public class Waiting6 {
public static void main (String [] args) {
System.out.println("Program starts");
MyThread2 t2 = new MyThread2();
MyThread1 t1 = new MyThread1(t2);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}

class MyThread1 extends Thread {
MyThread2 t2;
MyThread1 (MyThread2 t2) {
this.t2 = t2;
}
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running...");
synchronized(this) {
try {
t2.wait();
} catch(InterruptedException e) {}
}
}
}
}

class MyThread2 extends Thread {
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running***");
try {
System.out.println(name+" is sleeping...");
Thread.sleep(2000);
} catch(InterruptedException e) {}
synchronized(this) {
System.out.println(name+" will notify waiting thread...");
notify();
}
}
}
}

Runtime exception triggered
===========================
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:426)
at MyThread1.run(Waiting7.java:25)

Approach 2
==========
public class Waiting7 {
public static void main (String [] args) {
System.out.println("Program starts");
MyThread2 t2 = new MyThread2();
MyThread1 t1 = new MyThread1();
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}

class MyThread1 extends Thread {
MyThread2 t2 = new MyThread2();
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running...");
synchronized(this) {
try {
t2.wait();
} catch(InterruptedException e) {}
}
}
}
}

class MyThread2 extends Thread {
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name+" is running***");
try {
System.out.println(name+" is sleeping...");
Thread.sleep(2000);
} catch(InterruptedException e) {}
synchronized(this) {
System.out.println(name+" will notify waiting thread...");
notify();
}
}
}
}

Runtime exception triggered
===========================
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:426)
at MyThread1.run(Waiting7.java:25)
 
P

Peter J. Grey

lonelyplanet999 said:
I would like to ask is Thread class or it's subclass objects couldn't
use wait() method ?

i.e. a.wait() is not allowed if a is a Thread object instance or
object instance of Thread's subclass ?

synchronized/wait/notify will work on any object at all. However, a lock is a acquired by the current Thread at the point
where synchronized is executed, and I think you're running into some confusion because a Thread is acquiring a lock which is
also another Thread. Whether a Thread object is locked and whether a Thread is executing wait/notify are completely
separate concepts.

Peter
 
L

lonelyplanet999

Peter J. Grey said:
Hi!


You're calling wait() on a different object from the one you acquired the
synchronization lock for.
Try synchronized(t2) instead of synchronized(this). The other approach is
the same problem with the locks the other way around.

Tks:) It works now!
 
J

John C. Bollinger

lonelyplanet999 said:
I'm writing a program to make one thread periodically notifying
another regularly.

I tried 2 approaches. Both caused the waiting thead t1 triggered below
runtime exception:

[An IllegalMonitorStateException]

In order for a thread to invoke wait() (or notify(), or notifyAll()) on
an object, that thread must own the object's monitor. If it doesn't,
you get the exception shown. You obtain an object's monitor by
synchronizing _on that object_. In your wait calls you are
synchronizing on the running thread, not on the object you want to wait on.

It may help you understand what's going on better if you wait() and
notify() on some third object, rather than on one of the Threads. It
then becomes much clearer what's going on. This third object can be a
plain Object, and you don't need to do anything else special with it.


John Bollinger
(e-mail address removed)
 
J

John C. Bollinger

lonelyplanet999 said:
I would like to ask is Thread class or it's subclass objects couldn't
use wait() method ?

i.e. a.wait() is not allowed if a is a Thread object instance or
object instance of Thread's subclass ?

Thread is not special in this way. The wait() method is a final method
on Object, so you can be assured that it is not overridden on any class,
and therefore that it will work the same way for any object.


John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top