103 votes

Existe-t-il un ExecutorService qui utilise le thread actuel ?

Ce que je recherche, c'est un moyen compatible de configurer l'utilisation d'un pool de threads ou non. Idéalement, le reste du code ne devrait pas être impacté du tout. Je pourrais utiliser un pool de threads avec 1 thread mais ce n'est pas tout à fait ce que je veux. Des idées?

 ExecutorService es = threads == 0 ? new CurrentThreadExecutor() : Executors.newThreadPoolExecutor(threads);

// es.execute / es.submit / new ExecutorCompletionService(es) etc

73voto

overthink Points 9471

Voici une implémentation très simple de Executor (pas ExecutorService , remarquez) qui utilise uniquement le thread actuel. Voler cela de "Java Concurrency in Practice" (lecture essentielle).

 public class CurrentThreadExecutor implements Executor {
    public void execute(Runnable r) {
        r.run();
    }
}

ExecutorService est une interface plus élaborée, mais pourrait être gérée avec la même approche.

71voto

lpandzic Points 399

Style Java 8 :

Executor e = Runnable::run;

14voto

Eric Obermühlner Points 271

J'ai écrit un ExecutorService basé sur le AbstractExecutorService .

 /**
 * Executes all submitted tasks directly in the same thread as the caller.
 */
public class SameThreadExecutorService extends AbstractExecutorService {

    //volatile because can be viewed by other threads
    private volatile boolean terminated;

    @Override
    public void shutdown() {
        terminated = true;
    }

    @Override
    public boolean isShutdown() {
        return terminated;
    }

    @Override
    public boolean isTerminated() {
        return terminated;
    }

    @Override
    public boolean awaitTermination(long theTimeout, TimeUnit theUnit) throws InterruptedException {
        shutdown(); // TODO ok to call shutdown? what if the client never called shutdown???
        return terminated;
    }

    @Override
    public List<Runnable> shutdownNow() {
        return Collections.emptyList();
    }

    @Override
    public void execute(Runnable theCommand) {
        theCommand.run();
    }
}

7voto

Peter Lawrey Points 229686

Vous pouvez utiliser le RejectedExecutionHandler pour exécuter la tâche dans le thread actuel.

 public static final ThreadPoolExecutor CURRENT_THREAD_EXECUTOR = new ThreadPoolExecutor(0, 0, 0, TimeUnit.DAYS, new SynchronousQueue<Runnable>(), new RejectedExecutionHandler() {
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        r.run();
    }
});

Vous n'avez besoin que d'un seul d'entre eux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X