If I know the ID of the thread I wish to notify, and share no other common resource, can I notify it? Both the threads have been initiated by the same application.
the other thread went into wait by using Thread.currentThread().wait(500);
If I know the ID of the thread I wish to notify, and share no other common resource, can I notify it? Both the threads have been initiated by the same application.
the other thread went into wait by using Thread.currentThread().wait(500);
Yes - but you must stop using wait
.
The technique is to maintain a Map<String,BlockingQueue>
containing a queue for each thread that is running. The String
key is the thread ID.
When you want the thread to pause, use queue.poll(long, TimeUnit) instead of wait
. You merely need to put something in the queue to wake up the thread and obviously if you know the ID of the thread you can easily obtain it's Queue
from the Map
.
As long as it's in the same ThreadGroup, you can iterate through all the threads using Thread.enumerate() and find the given thread by it's id and do the usual synchronize and .notify().
This provides additional ways of iterating over all the Threads.
You would want to notify only threads waiting on the same lock. Don't use current thread object as the lock, it doesn't help. Once a thread has been awakened you need to check against a condition to guard against spurious wake ups. if you are sure that there is only one thread waiting on the lock then calling notify on the lock object should wake up the waiting thread.
You can give the threads some common object on which to communicate, and so you won't have to rely on thread names.
Example:
class Notifier extends Thread {
private final Object common;
Notifier(Object common) { this.common = common; }
public void run() {
// do work
synchronized (common) { common.notify(); }
}
}
class Waiter extends Thread {
private final Object common;
Waiter(Object common) { this.common = common; }
public void run() {
// do work
synchronized (common) { common.wait(TIMEOUT); }
}
}
A better yet approach would be to use a java.util.concurrent.CountDownLatch
for the same effect.
Yes it is possible. But it is ugly and potentially fragile and/or inefficient.
As @nos says you can use Thread.enumerate()
to enumerate the Thread
objects in your ThreadGroup
, test each one until you can find the thread with the expected name and/or thread id. That is clearly inefficient if there are lots of threads in the group.
The fragility arises in the following respects:
and on the synchronization side,
IMO, you would be better off creating (private) objects that you can wait/notify on, and using proper condition variables. Or it that is unappealing, use one of the existing higher level concurrency class for synchronizing.