Executor, ExecutorService, Executor - 1

"Bună, Amigo!"

„Nimic nu este perfect atunci când este creat pentru prima dată. Același lucru este valabil și pentru firele de execuție. În timp, creatorii Java s-au convins de deficiențele interfeței Runnable. Nu a acceptat aruncarea de excepții și nu a făcut posibilă aflarea rezultatul executării sarcinilor..."

„Interfața Runnable este mai potrivită pentru sarcini independente mari decât pentru subsarcini mici pe care doriți să le executați câte o duzină la un moment dat și apoi să le colectați rezultatele.”

„De aceea a fost inventată interfața Callable . Este mult mai potrivită pentru execuția paralelă a sarcinilor mici decât Runnable și Thread, în parte pentru că este o interfață generică.”

„Iată o implementare tipică a interfeței:”

Exemplu
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();
 }
}

„Spre deosebire de Runnable , aici trebuie să suprascriem metoda call, care returnează un rezultat de tipul specificat de argumentul tip. Această abordare este mult mai convenabilă decât metoda de rulare a interfeței Runnable, care returnează void. Uneori dezvoltatorii trebuiau să vină cu diverse soluții pentru a obține rezultatul unui thread."

"Înțeleg."

„Și acum uitați-vă la modul în care Callable poate lucra împreună cu ThreadPoolExecutor:

„În primul rând, metoda de trimitere a clasei ThreadPoolExecutor returnează un obiect Future parametrizat. Puteți utiliza acest obiect pentru a afla dacă o sarcină este terminată și pentru a obține rezultatul.”

"Iată cum funcționează:"

Exemplu
// 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();

"Departe! Îmi place în special clasa Viitorul. Ce metode are?"

„Iată cele mai interesante:”

Metodă Descriere
boolean cancel(boolean mayInterrupt);
Oprește sarcina.
boolean isCancelled();
Returnează adevărat dacă sarcina a fost oprită.
boolean isDone();
Returnează adevărat dacă sarcina este executată.
V get() throws InterruptedException, ExecutionException;
Returnează rezultatul metodei de apel sau aruncă o excepție dacă a apărut una.

„Mis! Așa că poți opri și sarcinile.”

„Nu vă bazați prea mult pe asta – nu orice fir se poate opri. Dar dacă o sarcină este încă în coadă, atunci aceasta va funcționa bine.”

„Îmi place această abordare. Este mult mai convenabil decât să creezi singur fire și apoi să încerci să scoți un rezultat din ele.”

— Grozav. Acolo vom încheia astăzi.