2015-08-16 5 views
3

У меня есть три потока, которые соединены, то есть второй поток выполняется после первых штампов.Как выполнять задачи в ExecutorService последовательно?

Это код, у меня есть:

public class Main { 
    public static void main(String args[]) throws Exception { 
     final Thread thrdA = new Thread(() -> System.out.println("Message 1")); 
     final Thread thrdB = new Thread(() -> System.out.println("Message 2")); 
     final Thread thrdC = new Thread(() -> System.out.println("Message 3")); 

     thrdA.start(); 
     thrdA.join(); 
     thrdB.start(); 
     thrdB.join(); 
     thrdC.start(); 
     thrdC.join(); 

    } 
} 

Как бы реализовать эту функцию, используя ExecutorService вместо трех объектов нить?

ответ

13

Если вам нужно/нужно выполнить группу заданий один за другим, но в одном потоке, отличном от основного потока приложения, используйте Executors#newSingleThreadExecutor.

ExecutorService es = Executors.newSingleThreadExecutor(); 
es.submit(() -> System.out.println("Message 1")); 
es.submit(() -> System.out.println("Message 2")); 
es.submit(() -> System.out.println("Message 3")); 
es.shutdown(); 
+0

Если это так, сообщения не выполняются в том порядке, в котором я запускаю потоки, например. выход должен быть «Сообщение 1», затем «Сообщение 2», затем «Сообщение 3». Они выполняются в случайном порядке, например. «Сообщение 2», «Сообщение 3», «Сообщение 1». То, что я пытаюсь сказать, заключается в том, как я могу выполнить runnable для каждого сообщения в службе-исполнителе, чтобы выход находился в порядке возрастания «Сообщение 1», затем «Сообщение 2», затем «Сообщение 3», а не случайный порядок, такой как «Сообщение 1», Сообщение 2 "," Сообщение 3 "," Сообщение 1 ". –

+0

Я думаю, что мое редактирование отвечает на то, что вы хотите/нуждаетесь. –

+0

Спасибо, я бы поднял, если бы мог –

3

Вы можете контролировать последовательное выполнение потоков с использованием SingleThread ExecutorService методом future.get().

DummyTask Класс

import java.util.concurrent.Callable; 

public class DummyTask implements Callable<Integer> 
{ 

int taskId; 

public DummyTask(int taskId) { 
    this.taskId = taskId; 
} 

@Override 
public Integer call() throws Exception 
{ 
    System.out.println("excuting task... Task Id: " + taskId); 
    return taskId; 
} 

} 

SequentialExecution Класс

package com.amit.executorservice; 

import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 

public class SequentialExecution 
{ 
public static void main(String[] args) throws InterruptedException, ExecutionException { 

    DummyTask task1 = new DummyTask(1); 
    DummyTask task2 = new DummyTask(2); 
    DummyTask task3 = new DummyTask(3); 
    Future<Integer> result = null; 
    ExecutorService executor = Executors.newSingleThreadExecutor(); 

    result = executor.submit(task1); 
    // future.get() Waits for the task to complete, and then retrieves its result. 
    result.get(); 

    result = executor.submit(task2); 
    // future.get() Waits for the task to complete, and then retrieves its result. 
    result.get(); 

    result = executor.submit(task3); 
    // future.get() Waits for the task to complete, and then retrieves its result. 
    result.get(); 

    executor.shutdown(); 

} 
} 

Выходной

excuting task... Task Id: 1 
excuting task... Task Id: 2 
excuting task... Task Id: 3 

Outpu t всегда будет одинаковым, и вся задача будет выполнена в последовательности.

+2

Ключевым здесь является 'Executors.newSingleThreadExecutor()', а не использование 'Future'. –

0

Если вы уже используете пул потоков в своем приложении, вы можете его повторно использовать с помощью прокси-сервера с нулевым потоком без создания специального однопоточного пула потоков. Одна реализация описана в javadoc section of Executor interface, другой, оптимизированной реализации, в моем репозитории Github CodeSamples.

Смежные вопросы