import java.util.*; public class Traadpulje { private List ledige = new ArrayList(); // Listen over ledige arbejdstråde /** Læg en opgave i kø til en arbejdstråd */ public synchronized void startOpgave(Runnable opgave) { Arbejder a; if (ledige.isEmpty()) { a = new Arbejder(); // ingen arbejdstråde ledige, en ny oprettes a.setDaemon(true); // tillad systemet at lukke ned selvom tråden er aktiv System.out.println("Ny arbejdstråd oprettet."); a.start(); } else synchronized(ledige) { a = (Arbejder) ledige.remove(ledige.size()-1);// tag arbejdstråd fra liste } synchronized(a) { if (a.opgave != null) throw new InternalError("Tråden kører allerede"); a.opgave = opgave; a.notify(); // væk arbejdstråden der venter i wait() } } /** * Arbejds-tråden. * Den er stærkt bundet til puljen så den er lagt som en privat indre klasse. */ private class Arbejder extends Thread { private Runnable opgave = null; public final synchronized void run() { while (true) try { if (opgave != null) { System.out.println(this+" virker nu på "+opgave); opgave.run(); // udfør opgaven opgave = null; // ... og glem den (!) synchronized(ledige) {ledige.add(this);} // læg tråd tilbage i listen } System.out.println(this+" venter på opgave."); this.wait(); // vent på at blive vækket med notify() } catch (Exception e) { System.err.println(this+": Fejl opstod i opgave "+opgave); e.printStackTrace(); } } // slut på run() } // slut på den indre klasse }