import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.Condition; public class RaceCondition1 { public static void main(String[] args) { // PannekakeStabel er en MONITOR! PannekakeStabel pannekakestabel = new PannekakeStabel(); // Lage ny kokk: (new Thread(new Kokk(pannekakestabel))).start(); // Lager nye personer for (int i = 0; i < 50; i++) { (new Thread(new Person(pannekakestabel))).start(); } } } class Person implements Runnable { static int IDCounter = 1; private int minID; PannekakeStabel pannekakestabel; // Bruker konstrukt?r til ? sette monitor (pannekakestabel) public Person(PannekakeStabel pannekakestabel) { minID = IDCounter ++; this.pannekakestabel = pannekakestabel; } // Hent en pannekake. public void run() { //System.out.println("Hei " + minID); System.out.println("Person " + minID + " henter en pannekake"); pannekakestabel.hentEnPannekake(); System.out.println("Person " + minID + " har hentet en pannekake"); } } class Kokk implements Runnable { private PannekakeStabel pannekakestabel; public Kokk(PannekakeStabel pannekakestabel) { this.pannekakestabel = pannekakestabel; } public void run() { for (int i = 0; i < 50; i ++) { System.out.println("Kokken lager en ny pannekake!"); pannekakestabel.settInnPannekake(); try { Thread.sleep(1500); } catch (Exception e) { } } } } class PannekakeStabel { private final Lock lock = new ReentrantLock(); private final Condition erTom = lock.newCondition(); int antallPannekaker = 0; public void settInnPannekake() { lock.lock(); try { antallPannekaker ++; erTom.signal(); } finally { lock.unlock(); } } public int hentEnPannekake() { lock.lock(); // 1: L?s l?sen try { // 2: Pr?v ? gj?re masse rart. while (antallPannekaker <= 0) { erTom.await(); } System.out.println(antallPannekaker); // KODE return antallPannekaker --; // 3: finally, l?s opp! } catch (InterruptedException ie) { System.out.println(ie); return -1; } catch (Exception e) { // await() return -1; } finally { lock.unlock(); } } }