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 / First Aid / February 2005

Tip: Looking for answers? Try searching our database.

How to notify specific thread??

Thread view: 
bunallo - 25 Feb 2005 02:43 GMT
If I have x number of threads that is waiting and I only want to notify a
specific thread how do I do this?

The situation is that I have some threads that needs to wait until a
specific object is inserted into a Database (made as a hashtable). When that
object is inserted into the database only the thread that waited for this
specific object is supposed to be notified.

I have made a notifyAll () call and then a while loop that checks if there
is one of all the newly notified that inserted the object. Each time this
while loop is false the wait is invoked on the thread.

But I would like to be able to notify only the correct thread. Heard this
could be done by making each thread lock on a unique object, but I can't
seem to make any sense out of it.

Hope someone can give me some ideas!
klynn47@comcast.net - 25 Feb 2005 02:49 GMT
I don't think there is anyway you can. The only way to make sure that
the thread you want is notified is by calling notifyAll().
Chris Smith - 25 Feb 2005 02:49 GMT
> If I have x number of threads that is waiting and I only want to notify a
> specific thread how do I do this?
[quoted text clipped - 11 lines]
> could be done by making each thread lock on a unique object, but I can't
> seem to make any sense out of it.

It is impossible to notify a specific thread that's waiting on a
monitor.  All you can do is notify all of them, or notify one of them
(chosen by no particular criteria).  You've already discovered that you
need to notify all of them.

The "while" loop you mentioned is called a predicate loop, is IT IS
ALWAYS REQUIRED TO CORRECTLY USE WAIT for any purpose.  Got that?  It's
not a symptom of bad design, and it's not something to be avoided or
worked around.  It has to be there.  It is just plain impossible to
write correct code to call Object.wait() without it.

If you need to optimize this code to avoid a "thundering herd" kind of
performance issue, then you can split the monitor into several monitors.  
There's a whole range of ways you can do this; in fact, a complete
continuum between using one monitor, as one extreme, or using a monitor
per object, as the other.  In between, you can create any constant
number of monitors, and categorize the objects between them somehow
(perhaps based on a digest of Object.hashCode() for instance).  You need
to provide more information if you want a more complete answer.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

bunallo - 25 Feb 2005 12:55 GMT
> If you need to optimize this code to avoid a "thundering herd" kind of
> performance issue, then you can split the monitor into several monitors.
[quoted text clipped - 4 lines]
> (perhaps based on a digest of Object.hashCode() for instance).  You need
> to provide more information if you want a more complete answer.

Ok I have tried something else:

Each time I create a thread it gets added to a vector v. In the run method
of this thread I have a flag. If this flag for some reason is set to true
then that current thread will be set to wait:

run(){

         if (flag_wait){
             synchronized(this){
             try{
                 flag_wait = false;
                 wait();
             }
             catch(InterruptedException e){}
         }
         }
}

If I create two threads and sets their flag_wait to true, I will now in my
vector v have two threads that are waiting at index 0 and index 1.

Now I create a third thread that should only notify thread a index 1.
Therefore I would like to have another type of thread that has a reference
to this vector and this in its run method:

run(){

         if (flag_notify){
             synchronized(this){
             try{

                 flag_notify = false;
                 v.get(1).notifyAll(); // now only thread at index 1 should
be notified!
             }
             catch(InterruptedException e){}
         }
         }
}

But for some reason I cannot run notifyAll() on a thread in a vector!

Hope its possible to understand
Tilman Bohn - 25 Feb 2005 13:41 GMT
[...]
> Each time I create a thread it gets added to a vector v. In the run method
> of this thread I have a flag. If this flag for some reason is set to true
[quoted text clipped - 4 lines]
>           if (flag_wait){
>               synchronized(this){

 You now synchronize on this Runnable. Without knowing your code it is
impossible to tell if that is the same object you end up putting in your
Vector, but let's assume it is (for now).

>               try{
>                   flag_wait = false;
>                   wait();

 Now the executing thread is added to the wait set associated with this
Runnable instance, and the lock is relinquished.

>               }
>               catch(InterruptedException e){}
>           }
>           }
> }

 You have already been told in no uncertain terms to _only_ _ever_
call wait() in a while loop. Please heed this advice. If you don't
believe it, don't start to argue but read the many many past threads
discussing this point first!

> If I create two threads and sets their flag_wait to true, I will now in my
> vector v have two threads that are waiting at index 0 and index 1.
[quoted text clipped - 6 lines]
>
>           if (flag_notify){

 For all I know, flag_notify could be false all the time so this block
might never run. How should anyone know?

>               synchronized(this){

 Now you synchronize on _this_ Runnable. That's certainly another
object than the one the wait() in the other thread is synchronizing on.

>               try{
>
>                   flag_notify = false;
>                   v.get(1).notifyAll(); // now only thread at index 1 should
> be notified!

 So at this point you are synchronized on the lock associated with this
Runnable instance, but very probably (impossible to say for sure without
seeing the rest of the code, but very probably) not on the one the
wait() above is using as a monitor. Therefore you will likely see an
IllegalMonitorStateException here.

>               }
>               catch(InterruptedException e){}
[quoted text clipped - 3 lines]
>
> But for some reason I cannot run notifyAll() on a thread in a vector!

 Did you get a CannotRunNotifyAllOnThreadInVectorException, or what
makes you say that?

Signature

Cheers, Tilman

`Boy, life takes a long time to live...'      -- Steven Wright

Chris Smith - 25 Feb 2005 14:16 GMT
> Each time I create a thread it gets added to a vector v. In the run method
> of this thread I have a flag. If this flag for some reason is set to true
> then that current thread will be set to wait:

On what?  You need a specific monitor to wait on.  That monitor needs to
be shared with other threads, which intend to call notify() on it.  I'm
not generally as picky about this as some other members of the group...
but you've shown yourself not very adept at supplying the information we
need in code snippets and error messages to answer your questions on the
newsgroup.  If you want help, the best thing for you to do is post
complete example code in the future, so that we can compile and run in
ourselves.

One more comment...

>           if (flag_wait){
>               synchronized(this){
[quoted text clipped - 4 lines]
>               catch(InterruptedException e){}
>           }

This lacks a predicate loop, and so it's hopelessly broken.  You need to
change the "if" statement to a "while" statement, and the notifying
thread needs to clear flag_wait, *not* the waiting thread.  The entire
predicate loop should be inside the synchronized block.

I'd also recommend that you forget all about optimizing until you've got
something working.  Use *one* shared object as a monitor, and not a
Vector or anything else.  Once that's working, you can try something
else.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Paul van Rossem - 25 Feb 2005 16:05 GMT
> If I have x number of threads that is waiting and I only want to notify a
> specific thread how do I do this?
[quoted text clipped - 13 lines]
>
> Hope someone can give me some ideas!

Use a java.util.concurrent.Semaphore (only available in 1.5).

Paul.
Tony Dahlman - 26 Feb 2005 03:32 GMT
>> If I have x number of threads that is waiting and I only want to notify a
>> specific thread how do I do this?
[quoted text clipped - 19 lines]
>
> Paul.
Ooh, what a package!

  http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html

BlockingQueue, a decoupling CompletionService, a ScheduledExecutorService, and
a ThreadFactory class.

Not to mention Semaphore, which maybe doesn't help the
OP.  ;-(  Can he/she really awaken just one of maybe a hundred wait()ing threads
without awakening them all?  I assume we don't know in advance in what order the
threads need to be awakened.

But never mind, because this package of classes and methods is, yes I think the
word is, "rad!"  If it all works as described in the API, Sun and Java may take
the entire market for ATM code and servers.

Normally, I try to stay two or three releases behind "the latest", to be sure
that any code I write will run anywhere, but a read through this package's API
makes me want to download 1.5 and start playing with the newest Java library.
(I may still wait a year or two, however.)

Thanks for the tip, Paul!

-- Tony Dahlman
Tilman Bohn - 26 Feb 2005 08:35 GMT
[...]
> Normally, I try to stay two or three releases behind "the latest", to be sure
> that any code I write will run anywhere, but a read through this package's API
> makes me want to download 1.5 and start playing with the newest Java library.
> (I may still wait a year or two, however.)

 No need to wait for 1.5. This is really an improved version of Doug
Lea's util.concurrent package, which you can also get for 1.4 under at
least two different guises. The original one (which actually works under
1.2+) at Oswego:

http://makeashorterlink.com/?X13F222E ,

or if you prefer to be able to easily switch to the official API later,
Dawid Kurzyniec's backport of this to 1.4:

http://www.mathcs.emory.edu/dcl/util/backport-util-concurrent/

Signature

Cheers, Tilman

`Boy, life takes a long time to live...'      -- Steven Wright



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.