{ "title": "Tråde", "solutions": "true" }
1

public class TennisSpiller extends Thread {
  private String navn;
  private boolean harBold;

  private TennisSpiller modstander;
  
  public TennisSpiller( String navn ) {
    this.navn = navn;
    
    harBold = false;
  }
  
  public void setModstander( TennisSpiller modstander ) {
    this.modstander = modstander;
  }
  
  public void modtagBold() {
    harBold = true;
  }
  
  public void run() {
    while ( true ) {
      while ( !harBold )
        Sleeper.nap();
      
      Sleeper.sleepRandom( 2 );
      
      if ( Math.random() > 0.20 ) {
        System.out.println( navn + " returnerer bolden" );
        harBold = false;
        modstander.modtagBold();
      } else {
        System.out.println( navn + " missede bolden" );
        break;
      }
    }
  }
}

  Bemærk at while-løkken, der venter på bolden, hele tiden vælge at sove i små tidsintervaller for på den måde ikke at "hamre" CPU'en.
  Vores testanvendelse instantierer to tennisspillere og giver bolden til den ene:
public class Main {

  public static void main( String[] argv ) {
  
    TennisSpiller spillerA = new TennisSpiller( "Andre Agassi" );
    TennisSpiller spillerB = new TennisSpiller( "Lleyton Hewitt" );
    
    spillerA.setModstander( spillerB );
    spillerB.setModstander( spillerA );
    
    spillerA.start();
    spillerB.start();
    
    spillerA.modtagBold();
  }
}

Andre Agassi returnerer bolden
Lleyton Hewitt returnerer bolden
Andre Agassi returnerer bolden
Lleyton Hewitt returnerer bolden
Andre Agassi returnerer bolden
Lleyton Hewitt missede bolden

 
2

public class CascadeThread extends Thread {
  private CascadeThread efterfølger;
  private String navn;
  private boolean minTur;
  
  public CascadeThread( String navn, CascadeThread efterfølger ) {
    this.navn = navn;
    this.efterfølger = efterfølger;
    
    minTur = false;
  }
  
  public void dinTur() {
    minTur = true;
  }
  
  public void run() {
    while ( !minTur )
      Sleeper.nap();
    
    System.out.println( navn );
    
    if ( efterfølger != null )
      efterfølger.dinTur();
  }
}

public class Main {

  public static void main( String[] argv ) {
    CascadeThread efterfølger = null;
    
    for ( int i=0; i<10; i++ ) {
      efterfølger = new CascadeThread( "Tråd " + i, efterfølger );
      efterfølger.start();
    }
    
    efterfølger.dinTur();
  }
}

Tråd 9
Tråd 8
Tråd 7
Tråd 6
Tråd 5
Tråd 4
Tråd 3
Tråd 2
Tråd 1
Tråd 0

 
3

public class PrioThread extends Thread {
  
  public void run() {
    Sleeper.sleep( 2.0 );
  
    System.out.println( this );
  }
  
  public String toString() {
    return "[PrioThread: prioritet=" + getPriority() + "]";
  }
}

public class Main {

  public static void main( String[] argv ) {
    
    for ( int i=Thread.MIN_PRIORITY; i<=Thread.MAX_PRIORITY; i++ ) {
      Thread tråde = new PrioThread();
      tråde.setPriority( i );
      tråde.start();
    }
  }
}

[PrioThread: prioritet=6]
[PrioThread: prioritet=10]
[PrioThread: prioritet=8]
[PrioThread: prioritet=9]
[PrioThread: prioritet=7]
[PrioThread: prioritet=5]
[PrioThread: prioritet=3]
[PrioThread: prioritet=4]
[PrioThread: prioritet=1]
[PrioThread: prioritet=2]

Som nævnt i opgaven bliver mønsteret ikke helt perfekt, men man ser tydeligt at trådene med høj prioritet bliver udført før dem med en lavere - og det selvom trådene startes med lavest prioritet først.