Home > Archive > Java Help > February 2005 > How to notify specific thread??
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
How to notify specific thread??
|
|
| bunallo 2005-02-25, 4:00 am |
| 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 2005-02-25, 4:00 am |
| 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 2005-02-25, 4:00 am |
| bunallo <nmnm@alala.com> wrote:
> 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.
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.
--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
| |
| bunallo 2005-02-25, 4:02 pm |
|
> 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.
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 2005-02-25, 4:02 pm |
| In message <cvn70f$q09$1@news.net.uni-c.dk>,
bunallo wrote on Fri, 25 Feb 2005 13:56:51 +0100:
[...]
> 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){
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.
>
>
> 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){
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){}
> }
> }
> }
>
>
> But for some reason I cannot run notifyAll() on a thread in a vector!
Did you get a CannotRunNotifyAllOnThreadInVectorExcept
ion, or what
makes you say that?
--
Cheers, Tilman
`Boy, life takes a long time to live...' -- Steven Wright
| |
| Chris Smith 2005-02-25, 4:02 pm |
| bunallo <nmnm@alala.com> wrote:
> 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){
> try{
> flag_wait = false;
> wait();
> }
> 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.
--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
| |
| Paul van Rossem 2005-02-25, 4:02 pm |
| On 25-02-2005 03:44, bunallo wrote:
> 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!
>
>
Use a java.util.concurrent.Semaphore (only available in 1.5).
Paul.
| |
| Tony Dahlman 2005-02-26, 3:59 am |
| Paul van Rossem wrote:
> On 25-02-2005 03:44, bunallo wrote:
>
>
> Use a java.util.concurrent.Semaphore (only available in 1.5).
>
> Paul.
Ooh, what a package!
http://java.sun.com/j2se/1.5.0/docs...ge-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 2005-02-26, 8:58 am |
| In message <421FEE0A.1030108@jps.net>,
Tony Dahlman wrote on Sat, 26 Feb 2005 03:33: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/uti...til-concurrent/
--
Cheers, Tilman
`Boy, life takes a long time to live...' -- Steven Wright
|
|
|
|
|