Java -避免不必要的线程唤醒



我有一组12个线程并行执行工作(Runnable)。实际上,每个线程都做以下工作:

Runnable r;
while (true) {
    synchronized (work) {
        while (work.isEmpty()) {
            work.wait();
        }
        r = work.removeFirst();
    }
    r.execute();
}

增加的工作如下:

Runnable r = ...;
synchronized (work) {
    work.add(r);
    work.notify();
}

当新工作可用时,它被添加到列表中并通知锁。如果有一个线程在等待,它被唤醒,所以它可以执行这项工作。

问题就在这里。当一个线程被唤醒时,很可能会有另一个线程执行这项工作。当后一个线程完成之前的工作并重新进入while(true)循环时,就会发生这种情况。工作动作越小/越短,发生这种情况的可能性就越大。

这意味着我正在无缘无故地唤醒一个线程。由于我需要高吞吐量,我认为这种行为会降低性能。

你怎么解决这个问题?理论上,我需要一种机制,允许我取消挂起的线程唤醒通知。当然,这在Java中是不可能的。

我想为每个线程引入一个工作列表。而不是把工作推到一个单独的列表中,工作被分散到12个工作列表中。但我相信这会带来其他问题。例如,一个线程可能有很多待处理的工作,而另一个线程可能没有待处理的工作。从本质上讲,我认为提前将工作分配给特定线程的解决方案可能会变得非常复杂,并且不是最优的。

谢谢!

你正在做的是一个线程池。看看java-5之前的并发框架,pooledexexecutor类:http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html

除了我之前的答案-另一个解决方案。这个问题使我很好奇。

这里,我添加了一个volatile boolean检查

它不能完全避免无用地唤醒线程的情况,但有助于避免这种情况。实际上,如果没有额外的限制,比如"我们知道在100ms之后,一个任务最有可能完成",我看不出这是如何完全避免的。

volatile boolean free = false;
while (true) {
    synchronized (work) {
        free = false;               // new rev.2
        while (work.isEmpty()) {
            work.wait();
        }
        r = work.removeFirst();
    }
    r.execute();
    free = true;        // new
}

,

synchronized (work) {
    work.add(r);
    if (!free) {         // new
         work.notify();
    }                    // new
    free = false;        // new rev.2
}

相关内容

  • 没有找到相关文章

最新更新