anna-k
anna-k

Reputation: 117

ExecutorService specify use new thread for each submitted task

I know the point of the ExecutorService is to recycle the same thread(s), but in this case I really need to specify to use a new thread for each submitted task.

Here is the initialization:

ExecutorService COMMAND_EXECUTOR_SERVICE = Executors.newFixedThreadPool(1);

When the command comes:

Task commandExecutionTask = new Task() {
        @Override
        protected Object call() {
            // do something with the command
        }
}

Then:

COMMAND_EXECUTOR_SERVICE.submit(commandExecutionTask);

How can I achieve that? The purpose is making sure the thread which just ran is garbage collected properly.

Upvotes: 2

Views: 1127

Answers (2)

Andy Turner
Andy Turner

Reputation: 140318

I really need to specify to use a new thread for each submitted task."

Why?

The purpose is making sure the thread which just ran is garbage collected properly.

If you need to care about this, you have a leaky abstraction. The only reason I can think is because you're using ThreadLocals, which are retaining the value between executions of the tasks.

Just use member variable with a lifetime within the task instead (e.g. member variables of instances created inside the task, and not retained).

Or add something at the end of running the tasks to ensure that the ThreadLocal values are cleaned up, e.g.

try {
  // Do stuff.
} finally {
  threadLocalVariable.remove();
}

Upvotes: 1

M. Prokhorov
M. Prokhorov

Reputation: 3993

This, in principle, is easy. However, the task where you would want this is very specific, and performs very badly in wide range of cases. Which is why there is no immediately ready implementation of executor service that does this in JDK (or at least not the visible to outside kind).

To implement an executor like this, we want an AbstractExecutorService as base, so we don't have to deal with managing Futures, and can concentrate on execution:

// If you search JDK, there is a class with this name.
// That has been taken as a general idea for this one.
public final class ThreadPerTaskExecutor extends AbstractExecutorService {
  @Override
  public void execute(Runnable task) {
    new Thread(task).start();
  }
}

I will again advise against going this route: staring a Thread in Java, especially for short and cheap tasks, is a relatively expensive operation that easily trumps almost any potential gains you get from using this class. You may still want to change the outside design so you don't need this.

Upvotes: 0

Related Questions