Executor, ExecutorService, Executor - 1

"Hej, Amigo!"

"Intet er perfekt, når det først oprettes. Det samme er tilfældet med tråde. Med tiden blev Javas skabere overbevist om manglerne ved Runnable-grænsefladen. Det understøttede ikke at smide undtagelser og gjorde det ikke muligt at finde ud af resultat af udførelse af opgaver..."

"Den Runnable-grænseflade er mere velegnet til store uafhængige opgaver end til små underopgaver, hvor du vil køre et dusin ad gangen og derefter samle deres resultater."

"Det er derfor Callable- grænsefladen blev opfundet. Den er meget bedre egnet til parallel udførelse af små opgaver end Runnable og Thread, til dels fordi det er en generisk grænseflade."

"Her er en typisk implementering af grænsefladen:"

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

"I modsætning til Runnable skal vi her tilsidesætte opkaldsmetoden, som returnerer et resultat af typen specificeret af typeargumentet. Denne tilgang er meget mere bekvem end Runnable-grænsefladens run-metode, som returnerer void. Nogle gange måtte udviklere komme med forskellige løsninger for at få en tråds resultat."

"Jeg ser."

"Og se nu på, hvordan Callable kan arbejde sammen med ThreadPoolExecutor:

"For det første returnerer ThreadPoolExecutor -klassens submit-metode et parameteriseret Future-objekt. Du kan bruge dette objekt til at finde ud af, om en opgave er færdig, og for at få resultatet."

"Sådan virker det:"

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

"Langt ude! Jeg kan især godt lide Future-klassen. Hvilke metoder har den?"

"Her er de mest interessante:"

Metode Beskrivelse
boolean cancel(boolean mayInterrupt);
Stopper opgaven.
boolean isCancelled();
Returnerer sandt, hvis opgaven blev stoppet.
boolean isDone();
Returnerer sandt, hvis opgaven udføres under udførelse.
V get() throws InterruptedException, ExecutionException;
Returnerer resultatet af opkaldsmetoden eller kaster en undtagelse, hvis en opstod.

"Fedt! Så du kan også stoppe opgaver."

"Lad være med at stole for meget på dette – ikke alle tråde kan stoppe. Men hvis en opgave stadig er i køen, vil dette fungere fint."

"Jeg kan godt lide denne tilgang. Det er meget mere praktisk end at skabe tråde selv og derefter prøve at trække et resultat ud af dem."

"Fantastisk. Det er der, vi slutter i dag."