wait og notify

For å slippe diverse dårlige/kreative løsninger som fort kan innebære mye knoting tilbyr Java wait() og notify() som gjør det enkelt for tråder å dele på de samme objektene.

Her er et enkelt og forståelig eksempel som tar utgangspunkt i det å være en vaskemaskin:

class Vaskemaskin {
 
   private static boolean klar = true;
   private static String klesvask = null;
 
   public synchronized void start(String møkketeKlesvask) throws InterruptedException {
      if (klesvask == null && klar) {
         klar = false; 
         klesvask = møkketeKlesvask;
         System.out.println("Starter vasking av " + klesvask);
         Thread.sleep(3000); // vi later som 3 sekund er 3 timer
         klar = true;
         notify(); // si i fra til ventende tråd
      } else {
         wait(); // vent
      }
   }
 
   public synchronized void tøm() throws InterruptedException {
      if (klesvask == null || !klar) {
         wait(); // vent
      } else {
         if (klesvask != null) {
            System.out.println("Tømmer vaskemaskin for " + klesvask);
            klesvask = null;
         }
         notify(); // si i fra til ventende tråd
      }
   }
}

Klassen Vaskemaskin tilbyr her bare to metoder – en for å starte en ny omgang og en for å tømme etterpå.

Begge er synkroniserte så programmet ville faktisk fungert uten notify() og wait(), problemet er da at tråden for å tømme vaskemaskinen stadig vil gjøre unødvendige kall på tøm().

For å teste denne klassen kan følgende benyttes:

private static Vaskemaskin vaskemaskin = new Vaskemaskin();

public static void main(String[] args) {

   // Sett på maskin
   new Thread(new Runnable() {
      public void run() {
         while (true) {
            try {
               vaskemaskin.start( klesvask() );
            } catch (InterruptedException ex) {}
         }
      }
   }).start();

   // Vent på maskin for å tømme
   new Thread(new Runnable() {
      public void run() {
         while (true) {
            try {
               vaskemaskin.tøm();
            } catch (InterruptedException ex) {}
         }
      }
   }).start();
}

public static String klesvask() {
 
   String[] klær = new String[] {
      "noen sokker", "litt håndklær", "ett dynetrekk",
      "noen putetrekk", "et par laken", "litt gensere", "noen bukser"
   };
 
   return klær[(int) (Math.random() * klær.length)];
}

.. som så gir et eller annet som ligner dette:

Starter vasking av litt håndklær
Tømmer vaskemaskin for litt håndklær
Starter vasking av noen sokker
Tømmer vaskemaskin for noen sokker
Starter vasking av litt håndklær
Tømmer vaskemaskin for litt håndklær
...

varargs

Som med C# og sikkert en rekke andre språk har også Java mulighet for å ha funksjoner/metoder som kan ta et ukjent antall innverdier.

Her er to slike funksjoner/metoder hvor man kan mate inn så mange String man vil:

public static void skrivUtMedMellomrom(String ... tekst) {
   String linje = "";
   for (String t : tekst) {
      linje += t + " ";
   }
   linje = linje.trim();
 
   System.out.println(linje);
}
public static void skrivUtMedMellomrom(int antallMellomrom, String ... tekst) {
   String linje = "";
   for (String t : tekst) {
      linje += t;
      for (int m = 0; m < antallMellomrom; m++) {
         linje += " ";
      }
   }
   linje = linje.trim();
 
   System.out.println(linje);
}

For å teste kan man for eksempel kjøre følgende:

public static void main(String[] args) {
   skrivUtMedMellomrom("Dette", "er", "en", "test!");
   skrivUtMedMellomrom(3, "I", "want", "cake!");
}

.. som gir:

Dette er en test!
I   want   cake!

String er ikke det eneste som er støttet selvsagt, alle typer kan benyttes.

Og signaturen trenger ikke være slik den er over – man har uendelig mange muligheter.