Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2006

Tip: Looking for answers? Try searching our database.

Simple(?) synchronized() block question

Thread view: 
noident@my-deja.com - 30 Jun 2006 02:45 GMT
Greetings!
I am trying to make a simple thread/conncurrency example work.
What I am trying to do in the following simple code example is:
1. Start a thread
2. Make the started thread become another object's (String s)  monitor
by executing a synchronized() statement
3. Call wait().
But it fails with an IllegalMonitorStateException.
If I understand the documentation correctly, I am under impression that
if the code within the synchronized() {} block is executing, the thread
is already the monitor of the object it's synchronizing on,  but that
seems not to be the case :(
The following simple program fails, and I can't figure out what's
wrong. I must be missing something simple.

import java.util.*;

public class Foo extends Thread
{
 private String s;
 public Foo(String ss) { s = ss; }

 public void run()
 {
   synchronized(s) // changing this line to 'synchronized(this)' fixes
the problem
   {
     try
     {
       wait();
     }
     catch(InterruptedException e)
     {
       System.err.println(e);
       System.exit(1);
     }
   }
 }

 public static void main(String[] args)
 {
   new Foo("abc").start();
 }
}

Running the above produces this:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
       at java.lang.Object.wait(Native Method)
       at java.lang.Object.wait(Object.java:474)
       at Foo.run(Foo.java:14)

my java version is:
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)

Any suggestions will be very much appreciated.
chins_inus@yahoo.com - 30 Jun 2006 03:02 GMT
Hi,
So basically u r getting this error coz u r calling wait method
implicitly on 'this' and synchronizing String s. so if u write s.wait()
it solves ur problem.

I hope it helps...

> Greetings!
> I am trying to make a simple thread/conncurrency example work.
[quoted text clipped - 53 lines]
>
> Any suggestions will be very much appreciated.
Patricia Shanahan - 30 Jun 2006 03:03 GMT
> Greetings!
> I am trying to make a simple thread/conncurrency example work.
[quoted text clipped - 8 lines]
> is already the monitor of the object it's synchronizing on,  but that
> seems not to be the case :(
...
>     synchronized(s) // changing this line to 'synchronized(this)' fixes
> the problem
[quoted text clipped - 3 lines]
>         wait();
>       }

In order to wait, you have to be in code synchronized on the object
whose wait method you are calling. You called, in effect, this.wait()
while synchronized on the string referenced by s. You must either
synchronize on this or call s.wait().

Patricia
noident@my-deja.com - 30 Jun 2006 03:16 GMT
Thank you very much to those who replied.
Of course! wait() is the Object's method, not the Thread's. My java
textbook mentioned that but didn't stress it well enough so I missed
it.
Thanks again.
Patricia Shanahan - 30 Jun 2006 03:21 GMT
> Thank you very much to those who replied.
> Of course! wait() is the Object's method, not the Thread's. My java
> textbook mentioned that but didn't stress it well enough so I missed
> it.
> Thanks again.

Note that even if the wait were somehow resolved for the thread rather
than "this", it could not tell which object to wait on. The thread can
be synchronized simultaneously on several different objects.

Patricia
Thomas Hawtin - 30 Jun 2006 16:43 GMT
> public class Foo extends Thread

Extending Thread is almost always a bad idea. If your book tells you to
do that, burn it.

> {
>   private String s;
[quoted text clipped - 4 lines]
>     synchronized(s) // changing this line to 'synchronized(this)' fixes
> the problem

Using a client supplied String for a lock isn't a great idea. The String
may be shared with the rest of the code in the JRE.

A handy little trick is to declare a nested or local class called Lock
with an empty body. The full name of classes are shown if you use
ctrl-\, ctrl-break, jstack or similar. A custom class name will help you
identify locks.

>     {
>       try
>       {
>         wait();

Even if the Thread was the right object to wait on, Thread is a bad
choice of lock. In Sun JVMs, Thread uses itself as a lock for internal
operations. Attempting to lock it yourself may give strange results.

You need to be careful what you synchronise on. An easy mistake is to
lock on an outer class instance, and then within in an inner class lock
on the inner class instance because this is different.

>       }
>       catch(InterruptedException e)
>       {
>         System.err.println(e);
>         System.exit(1);

Seems a little extreme...

>       }
>     }
[quoted text clipped - 5 lines]
>   }
> }

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.