Uitvoerder, UitvoerderService, Uitvoerder - 1

"Hallo Amigo!"

"Niets is perfect wanneer het voor het eerst wordt gemaakt. Hetzelfde geldt voor threads. Na verloop van tijd raakten de makers van Java overtuigd van de tekortkomingen van de Runnable-interface. Het ondersteunde het gooien van uitzonderingen niet en maakte het niet mogelijk om de resultaat van het uitvoeren van taken..."

"De Runnable-interface is geschikter voor grote onafhankelijke taken dan voor kleine subtaken die je met een dozijn tegelijk wilt uitvoeren en de resultaten daarvan wilt verzamelen."

"Daarom is de Callable- interface uitgevonden. Die is veel beter geschikt voor parallelle uitvoering van kleine taken dan Runnable en Thread, deels omdat het een generieke interface is."

"Hier is een typische implementatie van de interface:"

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

"In tegenstelling tot Runnable moeten we hier de call-methode overschrijven, die een resultaat retourneert van het type dat wordt gespecificeerd door het type-argument. Deze aanpak is veel handiger dan de run-methode van de Runnable-interface, die ongeldig retourneert. Soms moesten ontwikkelaars iets bedenken verschillende oplossingen om het resultaat van een thread te krijgen."

"Ik zie."

"En kijk nu hoe Callable kan samenwerken met ThreadPoolExecutor:

"Ten eerste retourneert de verzendmethode van de ThreadPoolExecutor- klasse een geparametriseerd Future-object. U kunt dit object gebruiken om erachter te komen of een taak is voltooid en om het resultaat te krijgen."

"Dit is hoe het werkt:"

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

"Ver weg! Ik hou vooral van de Future-klasse. Welke methoden heeft deze?"

"Hier zijn de meest interessante:"

Methode Beschrijving
boolean cancel(boolean mayInterrupt);
Stopt de taak.
boolean isCancelled();
Retourneert waar als de taak is gestopt.
boolean isDone();
Retourneert waar als de taak wordt uitgevoerd.
V get() throws InterruptedException, ExecutionException;
Retourneert het resultaat van de aanroepmethode of genereert een uitzondering als er een is opgetreden.

"Cool! Je kunt dus ook taken stoppen."

"Vertrouw hier niet te veel op - niet elke thread kan stoppen. Maar als een taak nog in de wachtrij staat, werkt dit prima."

"Ik hou van deze aanpak. Het is veel handiger dan zelf threads maken en er dan een resultaat uit proberen te halen."

"Geweldig. Daar eindigen we vandaag."