0

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);

Sam
  • 95
  • 1
  • 9
  • You don't `notify` a thread - you notify waiters on an object. You can however `interrupt` a particular thread. – davmac Feb 27 '14 at 14:07

5 Answers5

1

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.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • Is there any advantage to using the blockingqueue over waiting/notifying on any regular object? – Sam Feb 28 '14 at 09:38
  • @Sam - Yes! It is much more flexible and handles all of the edge conditions inherent in the Wait/Notify system properly. In my opinion there is nothing you can do using Wait/Notify that you cannot do properly with one of the new java.util.concurrent objects. – OldCurmudgeon Feb 28 '14 at 12:25
  • I like this answer, but I wanna differentiate between the case where it receives the signal from the other thread(as an addition to the queue) and when it polls out, and execute different code accordingly, I'm not able to do that, could you suggest anything? This http://stackoverflow.com/questions/22063249/how-to-make-a-thread-wait-for-a-notify-for-a-specific-time-and-execute-code-acco/22079635?noredirect=1#22079635 is my real question..! – Sam Mar 01 '14 at 04:35
0

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.

Community
  • 1
  • 1
nos
  • 223,662
  • 58
  • 417
  • 506
0

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.

nitnamby
  • 404
  • 2
  • 8
  • Given that the two threads involved are started in really different parts of the code, such that neither of them are linked to each other much, would that mean, I would have to go to the main starting file, and pass an object to both these threads? – Sam Feb 27 '14 at 11:44
  • I guess you want one thread to notify other because action of one thread depends on the previous action of the other thread. You need to have a common lock for inter thread communication. if two threads are not related at all then why wouldn't need any coordination between them. – nitnamby Feb 27 '14 at 14:23
  • Actually my question is linked to this http://stackoverflow.com/questions/22063249/how-to-make-a-thread-wait-for-a-notify-for-a-specific-time-and-execute-code-acco?noredirect=1#comment33456544_22063249 One of the threads here is just a listen thread, which should notify the other thread if it receives a specific kind of packet... So far I suppose I would have to use a common resource. – Sam Feb 27 '14 at 18:24
0

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.

afsantos
  • 5,178
  • 4
  • 30
  • 54
0

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:

  • The thread with a given name or id may no longer exist.
  • There could be multiple threads with the same name.
  • Thread id values will eventually be recycled when enough threads have been and gone.

and on the synchronization side,

  • There could conceivably be other parts of your application (or library code) that synchronize using wait/notify on the Thread objects, and you could get unwanted notifies as a result.
  • On some Java platforms, (at least historically) it is possible to get spontaneous notifications ... so using wait / notify without testing a shared condition variable might result in bad synchronization.

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216