How can I wait () on one object and then notify about it another?

I believe that the problem I am facing is an option to lock the nested monitor. Basically, I have two thread groups (not ThreadGroups, only logical groups). One group of threads (say, a background group) will wait for an object while another group of threads is working (work group). One by one, the workflows exit until finally the last workflow is in the "full" method. What I want to do is figure out some way to let this last worker thread wait, and then call notifyAll () to wake up all the background threads. As you can guess, two groups of threads switch back and forth - one group works while the other waits, and then the groups switch. The problem is that if I notifyAll () for current pending threads, then there is no guaranteethat the final worker thread will do this to the wait () call until the notified threads complete and try to start the next swap.

Sorry if this question is a bit off - it seems the more I work on concurrency, the more confusing my code will be: (

+3
source share
4 answers

You can try connecting thread groups using Exchanger . It is classically used to transfer work back and forth between two threads that alternate with work. It looks like you can probably make it work for thread groups too, if you can make the translation work correctly.

, ? AllAll , Exchanger, . , Exchanger.

, , CyclicBarrier , , , . Exchanger SynchronousQueue ( 0- , ).

Java Concurrency DZone Concurrency refcard.

+1

, - Gate, CountDownLatch. .

gate.ready(), gate.go()

, 1 . , go .

/**
 * Simple starting gate for co-ordinating a bunch of threads.
 */
final class Gate {
  final CountDownLatch ready;
  final CountDownLatch go = new CountDownLatch(1);

  Gate(final int threads) {
    ready = new CountDownLatch(threads);
  }

  /**
   * Called from the racing threads when ready. They will then block until all
   * threads are at this point;
   */
  void ready() {
    ready.countDown();
    await(go);
  }

  /**
   * Called from the starter thread. Blocks until everybody is ready, and then
   * signals go.
   */
  void go() {
    await(ready);
    go.countDown();
  }

  static void await(final CountDownLatch latch) {
    try {
      if (!latch.await(5, TimeUnit.SECONDS)) { // arbitrary, parameterise for production use
        throw new TimedOutException()
      }
    } catch (final InterruptedException e) {
      throw new RuntimeException(e);
    }
  }

  static final class TimedOutException extends IllegalStateException {}
}

, , , - Doug Lea Phaser, Java7.

+2

, , . , , :

synchronized void completed() {
    threads_working--;
    if (threads_working == 0) {
        synchronized (some_lock) {
            some_lock.notifyAll();
        }
    }
}

And each thread should increase this number when it starts working.

0
source

Is it possible to allow threads to return and terminate, rather than wait? If so, have you considered implementing a thread manager to spawn threads and initiate control for each group?

threaded process:

public void run()
{
    while (workRemaining())
    {
        doWork();
    }
    this.manager.workCompleted();
}

and inside the thread manager:

void workCompleted()
{
    if (--this.runningThreads <= 0)
    {
        spawnNewGroup();
    }
}

void spawnNewGroup()
{
    for (int i=0; i<groupSize; i++)
    {
        startIndividualThread();
        this.runningThreads++;
    }
}
0
source

Source: https://habr.com/ru/post/1777374/


All Articles