Reduce execute-produce-consume excessive thread spawning.

Defer the clearing of hasThreadPending flag until about to produce a task,
inside synchronized block.

This gives a new thread a chance to produce at least once before other threads
decide to spawn new threads.

Previously there could be an excessive number of unncessary threads,
all waiting for their initial attempt to produce a task.
This commit is contained in:
catbref 2019-07-12 13:27:01 +01:00
parent b038e10ee7
commit 9ee12f3e45

View File

@ -74,6 +74,7 @@ public abstract class ExecuteProduceConsume implements Runnable {
public void run() {
Thread.currentThread().setName(className + "-" + Thread.currentThread().getId());
boolean wasThreadPending;
synchronized (this) {
++activeThreadCount;
if (activeThreadCount > greatestActiveThreadCount)
@ -82,7 +83,8 @@ public abstract class ExecuteProduceConsume implements Runnable {
logger.trace(() -> String.format("[%d] started, hasThreadPending was: %b, activeThreadCount now: %d",
Thread.currentThread().getId(), hasThreadPending, activeThreadCount));
hasThreadPending = false;
// Defer clearing hasThreadPending to prevent unnecessary threads waiting to produce...
wasThreadPending = hasThreadPending;
}
try {
@ -94,6 +96,12 @@ public abstract class ExecuteProduceConsume implements Runnable {
logger.trace(() -> String.format("[%d] waiting to produce...", Thread.currentThread().getId()));
synchronized (this) {
if (wasThreadPending) {
// Clear thread-pending flag now that we about to produce.
hasThreadPending = false;
wasThreadPending = false;
}
final boolean lambdaCanIdle = canBlock;
logger.trace(() -> String.format("[%d] producing, canBlock is %b...", Thread.currentThread().getId(), lambdaCanIdle));
task = produceTask(canBlock);