© Harry Broeders.
In deze practicum opdracht maak je kennis met Java. We zullen hetzelfde producer/consumer programma uit opgave 2 als voorbeeld gebruiken. Ook zullen we de scheduling eigenschappen van Java bestuderen.
De gratis ontwikkelomgeving voor Java van Sun is in lokaal 428 zowel in de WindowsXP als in de Linux installatie opgenomen.
Er zijn diverse andere (gratis) ontwikkelomgevingingen beschikbaar:
Het is handig om ook de documentatie en tutorial bij de hand te hebben in 428:
Opdracht 3a.Installeer een Java ontwikkelomgeving naar keuze en test deze door een eenvoudig "Hello world" programma te schrijven. |
We gebruiken in deze opgave hetzelfde voorbeeld als in opgave 2.
De class BoundedBuffer
is in de file
BoundedBuffer.java als volgt gedefinieerd:
public class BoundedBuffer { private char buffer[]; private int indexPut; private int indexGet; private int numberInBuffer=0; private int size; public BoundedBuffer(int length) { size=length; buffer=new char[size]; indexPut=0; indexGet=0; } public synchronized void put(char c) throws InterruptedException { while (numberInBuffer==size) wait(); buffer[indexPut++]=c; indexPut%=size; numberInBuffer++; notify(); } public synchronized char get() throws InterruptedException { while (numberInBuffer==0) wait(); char c=buffer[indexGet++]; indexGet%=size; numberInBuffer--; notify(); return c; } }
De links in het programma verwijzen naar de
online API documentatie
van Sun. Met behulp van de method put
kan een karakter in de
BoundedBuffer
worden geschreven en met behulp van de method
get
kan een karakter uit de BoundedBuffer
worden
gelezen.
De class Consumer
is in de file
Consumer.java gedefinieerd:
public class Consumer implements Runnable { public Consumer(BoundedBuffer bb) { b=bb; } public void run() { try { synchronized (System.out) { System.out.println("Thread: "+Thread.currentThread().getName()+" gestart"); } for (int i=0; i<2000; ++i) { char c=b.get(); synchronized (System.out) { System.out.print(c); } } synchronized (System.out) { System.out.println("Thread: "+Thread.currentThread().getName()+" gestopt"); } } catch(InterruptedException e) { System.err.println("Thread: "+Thread.currentThread().getName()+" interrupted"); } } private BoundedBuffer b; }
Er worden 2000 karakters uit de buffer gelezen met behulp van de method
get
. Elk karakter wordt met de method print
op
het scherm (System.out
) gezet. Ook wordt het starten en stoppen
van de thread gemeld.
De class Producer
moet in de file
Producer.java gedefinieerd worden:
public class Producer implements Runnable { /* Implementeer hier de Producer Deze producer moet 1000 x het karakter dat als eerste argument aan de constructor wordt meegegeven in de buffer plaatsen dat als tweede argument aan de constructor wordt meegegeven. */ }
In de file TestBoundedBuffer.java is het test programma gedefinieerd:
public class TestBoundedBuffer { public static void main(String[] args) { if (args.length!=3) { System.err.println("Usage: java TestBoundedBuffer <Priority Consumer> "+ "<Priority Frikadel Producer> <Priority Kroket Producer>"); System.err.println("Minimum Priority = "+Thread.MIN_PRIORITY); System.err.println("Maximum Priority = "+Thread.MAX_PRIORITY); System.err.println("Normal Priority = "+Thread.NORM_PRIORITY); } else { BoundedBuffer b=new BoundedBuffer(16); char frikadel='F'; char kroket='K'; Thread.currentThread().setPriority(Thread.MAX_PRIORITY); Thread tc =new Thread(new Consumer(b)); Thread tp1=new Thread(new Producer(frikadel, b)); Thread tp2=new Thread(new Producer(kroket, b)); tc.setPriority(Integer.parseInt(args[0])); tp1.setPriority(Integer.parseInt(args[1])); tp2.setPriority(Integer.parseInt(args[2])); System.out.println("Output voor Consumer priority = "+tc.getPriority()+ " Frikadel Producer priority = "+tp1.getPriority()+ " Kroket Producer priority = "+tp2.getPriority()); tc.start(); tp1.start(); tp2.start(); } } }
In de method main
krijgt de main thread een hoge prioriteit.
De main thread moet de hoogste prioriteit hebben omdat deze thread de andere
threads start en we willen de onderlinge wisselwerking van deze threads
bestuderen.
In dit programma "bakt" de ene producer frikadellen (weergegeven met de letter
F
) en "bakt" de andere producer kroketten (weergegeven met de
letter K
). De consumer "eet" de frikadellen en kroketten op.
Bij het starten van het programma moeten op de command line 3 parameters worden meegegeven. Dit zijn achtereenvolgens de prioriteit van de consumer, de prioriteit van de frikadellen producer en de prioriteit van de kroketten producer.
De main thread hoeft in Java niet te wachten totdat de andere threads geëindigd zijn. Het proces wordt pas beëindigen als alle threads zijn beëindigd.
Opdracht 3d.
Vervang in de code van de class java TestBoundedBuffer 1 2 3 Verklaar de verschillen in de uitvoer vergeleken met opgave 3b en opgave 3c. Test ook de volgende prioriteiten: java TestBoundedBuffer 3 2 1 Verklaar de uitvoer! Is de uitvoer deterministisch? |