Executor, ExecutorService, Executor - 1

"Cześć, Amigo!"

„Nic nie jest idealne od razu po stworzeniu. Tak samo jest z wątkami. Z czasem twórcy Javy przekonali się o wadach interfejsu Runnable. Nie obsługiwał on rzucania wyjątków i nie pozwalał wykryć wynik wykonywania zadań…”

„Interfejs Runnable jest bardziej odpowiedni do dużych niezależnych zadań niż do małych podzadań, które chcesz uruchomić kilkanaście naraz, a następnie zebrać ich wyniki”.

„Dlatego wynaleziono interfejs Callable . Znacznie lepiej nadaje się do równoległego wykonywania małych zadań niż Runnable i Thread, po części dlatego, że jest interfejsem ogólnym”.

„Oto typowa implementacja interfejsu:”

Przykład
class ReverseString implements Callable<String>
{
 String str;

 ReverseString(String str)
 {
  this.str = str;
 }

 public String call() throws Exception
 {
  StringBuilder builder = new StringBuilder(str);
  builder.reverse();
  return builder.toString();
 }
}

„W przeciwieństwie do Runnable tutaj musimy zastąpić metodę call, która zwraca wynik typu określonego przez argument type. Takie podejście jest znacznie wygodniejsze niż metoda run interfejsu Runnable, która zwraca void. Czasami programiści musieli wymyślić różne obejścia, aby uzyskać wynik wątku”.

"Widzę."

„A teraz spójrz, jak Callable może współpracować z ThreadPoolExecutor:

„Po pierwsze, metoda przesyłania klasy ThreadPoolExecutor zwraca sparametryzowany obiekt Future. Możesz użyć tego obiektu, aby dowiedzieć się, czy zadanie zostało zakończone, i uzyskać wynik”.

"Oto jak to działa:"

Przykład
// 1. Create a ThreadPoolExecutor
ExecutorService service = Executors.newFixedThreadPool(5);

// 2. Add a task to it
Future<String> task = service.submit(new ReverseString("Amigo"));

// 3. Wait until the task is done
while(!task.isDone())
{
 Thread.sleep(1);
}

// 4. Try to get the result
//We will get either the result, or an exception if one occurred while the task was being executed
try
{
 System.out.println("Full string : " + task.get());
}
catch (Exception ie)
{
 ie.printStackTrace(System.err);
}

// 5. Stop the ThreadPool.
service.shutdown();

„Daleko! Szczególnie podoba mi się klasa Future. Jakie ma metody?”

„Oto najciekawsze:”

metoda Opis
boolean cancel(boolean mayInterrupt);
Zatrzymuje zadanie.
boolean isCancelled();
Zwraca true, jeśli zadanie zostało zatrzymane.
boolean isDone();
Zwraca true, jeśli zadanie jest wykonywane.
V get() throws InterruptedException, ExecutionException;
Zwraca wynik wywołania metody lub zgłasza wyjątek, jeśli taki wystąpił.

„Fajnie! Więc możesz także zatrzymywać zadania”.

„Nie polegaj na tym zbytnio — nie każdy wątek może się zatrzymać. Ale jeśli zadanie nadal znajduje się w kolejce, to zadziała dobrze”.

„Podoba mi się to podejście. Jest o wiele wygodniejsze niż samodzielne tworzenie wątków, a następnie próba wyciągnięcia z nich wyniku”.

„Świetnie. Na tym dzisiaj zakończymy”.