2

I have a thread which must wait several objects from different threads.

@Override
public void run() {
    while (true) {
        for (BackgroundTask task : tasks) {
            synchronized (task) {
                if (task.isReady()) {
                    task.doTask();
                }
            }
        }
    }
}

But it is a stupid use of CPU time. How to wait several objects?

itun
  • 3,439
  • 12
  • 51
  • 75

4 Answers4

3

IMO CountDownLatch would be a good way of going about it. Quoting from the Javadoc:

 class Driver2 { // ...
   void main() throws InterruptedException {
     CountDownLatch doneSignal = new CountDownLatch(N);
     Executor e = ...

     for (int i = 0; i < N; ++i) // create and start threads
       e.execute(new WorkerRunnable(doneSignal, i));

     doneSignal.await();           // wait for all to finish
   }
 }

 class WorkerRunnable implements Runnable {
   private final CountDownLatch doneSignal;
   private final int i;
   WorkerRunnable(CountDownLatch doneSignal, int i) {
      this.doneSignal = doneSignal;
      this.i = i;
   }
   public void run() {
      try {
        doWork(i);
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }
Sanjay T. Sharma
  • 22,857
  • 4
  • 59
  • 71
  • I think that BlockingQueue is more convenient for my case. Because your suggestion is good for tasks int several threads, and I need one long-live thread for several tasks. – itun Mar 28 '11 at 14:52
  • @itun: You said "wait several objects from different threads", that's why I assumed that you have multiple threads running, processing something which the driver thread needs to wait for. You can easily adapt the code posted for your scenario and it should work flawlessly. :-) – Sanjay T. Sharma Mar 28 '11 at 15:29
  • I don` t know how to do this. doneSignal will wait when all objects will be ready, but I need that driver waits until at least one will not be ready – itun Mar 28 '11 at 19:29
  • @itun: Basically, you can have callback handlers in your Runnable classes. These callback handlers would be executed when the run() method completes its processing. This gives you the flexibility of notifying multiple sources that the runnable has completed its work. – Sanjay T. Sharma Mar 29 '11 at 05:16
1

If you can modify the BackgroundTask class, have it notify your runner when it is ready. Add a queue to your runner class, and each time a task is ready, it can add itself to the queue and notify it.

The runner class then waits on the queue when it is empty, and pulls items out of it to run when it is not.

Jonathan
  • 13,354
  • 4
  • 36
  • 32
1

Please use notifyaAll() instead of notify() because notify wakes up single thread where as notifyAll() wakes up all the waiting threads.

allthenutsandbolts
  • 1,513
  • 1
  • 13
  • 34
  • As far as I know notifyAll() is wake up only one objects in all waiting threads. I need to wait several object in one thread. – itun Mar 28 '11 at 14:16
  • @itun thread waiting is completely serial. That is, only one thread can wait on one object (monitor) at any given time. This violates what type of functionality you are looking for and is not available. – John Vint Mar 28 '11 at 14:18
  • wait and notify have several caveats (like threads being woken up when notify hasn't been called). You should use higher level components such as a BlockingQueue or CountDownLatch. – Matt Wonlaw Mar 28 '11 at 14:28
  • @mlaw I guess I explained myself incorrectly. I meant that a thread can only wait on one object. Not necessarily one thread and only one thread can wait on one object. – John Vint Mar 28 '11 at 15:26
  • @John ah. I appologize. I should have read itun's comment more closely. – Matt Wonlaw Mar 28 '11 at 16:42
0

You can utilize notify() and wait() on the Object. How you use it depends on the struture of your program.

vbence
  • 20,084
  • 9
  • 69
  • 118
  • It would be good to mention here that when one object waits on another, the waiting object may be woken up without notify having ever been called. That is, wait must always be called in a loop which checks a condition. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4308396 – Matt Wonlaw Mar 28 '11 at 14:32