Università degli Studi della Calabria Corso di Laurea in Ingegneria Informatica A.A. 2001/2002 Sistemi Operativi Corsi A e B Esercitazioni 7 e 8 Bounded Buffer con sincronizzazione Java (1) public class BoundedBuffer { private int buffer[]; private int in=0, out=0, count=0, dim; public BoundedBuffer (int dim) { this.dim=dim; buffer=new int[dim]; } public synchronized int get () { /* lucidi seguenti */ } public synchronized void put (int item) { /* lucidi seguenti */ } } Sistemi Operativi P.Trunfio – R.Ortale Bounded Buffer con sincronizzazione Java (2) public synchronized int get () { while (count==0) { try { wait(); } catch (InterruptedException e) { } } int item = buffer[out]; out=(out+1)%dim; count--; notifyAll(); return item; } Sistemi Operativi P.Trunfio – R.Ortale Bounded Buffer con sincronizzazione Java (3) public synchronized void put (int item) { while (count==dim) { try { wait(); } catch (InterruptedException e) { } } buffer[in] = item; in=(in+1)%dim; count++; notifyAll(); } Sistemi Operativi P.Trunfio – R.Ortale Bounded Buffer con sincronizzazione Java (4) public class Consumer extends Thread { private BoundedBuffer buffer; private int id; public Consumer (BoundedBuffer buffer, int id) { this.buffer = buffer; this.id = id; } public void run () { for (int i=0; i<10; i++) { int value = buffer.get(); System.out.println ("Consumer #"+id+" ha estratto "+value); } } } Sistemi Operativi P.Trunfio – R.Ortale Bounded Buffer con sincronizzazione Java (5) public class Producer extends Thread { private BoundedBuffer buffer; private int id; public Producer (BoundedBuffer buffer, int id) { this.buffer = buffer; this.id = id; } public void run () { for (int i=0; i<10; i++) { buffer.put(i); System.out.println ("Producer #"+id+" ha inserito "+i); } } } Sistemi Operativi P.Trunfio – R.Ortale Bounded Buffer con sincronizzazione Java (6) public class BBTest { public static void main (String args[]) { BoundedBuffer bb = new BoundedBuffer (10); Producer pv[] = new Producer [5]; for (int i = 0; i < 5; i++) { pv[i] = new Producer (bb,i); pv[i].start(); } Consumer cv[] = new Consumer [9]; for (int i = 0; i < 9; i++) { cv[i] = new Consumer (bb,i); cv[i].start(); } } } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con sincronizzazione Java (1) public class Database { private int readerCount; private boolean dbReading; private boolean dbWriting; public Database() { readerCount = 0; dbReading = false; dbWriting = false; } public synchronized int startRead() { /* lucidi seguenti */ } public synchronized int endRead() { /* lucidi seguenti */ } public synchronized void startWrite() { /* lucidi seguenti */ } public synchronized void endWrite() { /* lucidi seguenti */ } } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con sincronizzazione Java (2) public synchronized int startRead() { while (dbWriting == true) { try { wait(); } catch (InterruptedException e) { } } ++readerCount; if (readerCount == 1) dbReading = true; return readerCount; } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con sincronizzazione Java (3) public synchronized int endRead() { --readerCount; if (readerCount == 0) { dbReading=false; notifyAll(); } return readerCount; } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con sincronizzazione Java (4) public synchronized void startWrite() { while (dbReading == true || dbWriting == true) { try { wait(); } catch (InterruptedException e) { } } dbWriting = true; } public synchronized void endWrite() { dbWriting = false; notifyAll(); } Sistemi Operativi P.Trunfio – R.Ortale Blocchi sincronizzati (1) n Anche blocchi di codice, oltre che interi metodi, possono essere dichiarati synchronized. n Ciò consente di associare un lock la cui durata è tipicamente inferiore a quella di un intero metodo synchronized. Sistemi Operativi P.Trunfio – R.Ortale Blocchi sincronizzati (2) public void syncronized F() { // sezione non critica (p.es.: inizializzazione di variabili locali) // sezione critica // sezione non critica } public void F() { // sezione non critica synchronized (this) { // sezione critica } // sezione non critica } Sistemi Operativi P.Trunfio – R.Ortale Semafori in Java (1) n Java non fornisce semafori, ma una classe semaforo può essere costruita usando i meccanismi di sincronizzazione di Java. Sistemi Operativi P.Trunfio – R.Ortale Semafori in Java (2) public class Semaphore { private int value; public Semaphore() { value = 0; } public Semaphore(int v) { value = v; } public synchronized void P () { /* lucidi seguenti */ } public synchronized void V () { /* lucidi seguenti */ } } Sistemi Operativi P.Trunfio – R.Ortale Semafori in Java (3) public synchronized void P () { if (--value < 0) { try { wait(); } catch (InterruptedException e) { } } } Sistemi Operativi P.Trunfio – R.Ortale Semafori in Java (4) public synchronized void V () { if (++value <= 0) notify (); } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con semafori Java (1) public class Reader extends Thread { private Database server; public Reader (Database db) { server = db; } public void run () { int c; while (true) { c = server.startRead(); /* lettura dal database */ c = server.endRead(); } } } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con semafori Java (2) public class Writer extends Thread { private Database server; public Writer (Database db) { server = db; } public void run () { while (true) { server.startWrite(); /* scrittura sul database */ server.endWrite(); } } } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con semafori Java (3) public class Database { private int readerCount; // numero di lettori attivi private Semaphore mutex; // per l’accesso a readerCount private Semaphore db; // per l’accesso al database public Database () { readerCount = 0; mutex = new Semaphore(1); db = new Semaphore(1); } public int startRead() { /* lucidi seguenti */ } public int endRead() { /* lucidi seguenti */ } public void startWrite() { /* lucidi seguenti */ } public void endWrite() { /* lucidi seguenti */ } } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con semafori Java (4) public int startRead () { mutex.P(); ++readerCount; if (readerCount == 1) db.P(); mutex.V(); return readerCount; } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con semafori Java (5) public int endRead() { mutex.P(); --readerCount; if (readerCount == 0) db.V(); mutex.V(); return readerCount; } Sistemi Operativi P.Trunfio – R.Ortale Lettori-Scrittori con semafori Java (6) public void startWrite() { db.P(); } public void endWrite() { db.V(); } Sistemi Operativi P.Trunfio – R.Ortale Cinque Filosofi con semafori Java (1) public class Filosofo extends Thread { private int id; private Semaphore destro, sinistro; public Filosofo (int id, Semaforo dx, Semaforo sx) { this.id=id; destro=dx; sinistro=sx; } public void run () { while (true) { /* pensa */ destra.P(); sinistra.P(); /* mangia */ destra.V(); sinistra.V(); } } } Sistemi Operativi P.Trunfio – R.Ortale Cinque Filosofi con semafori Java (2) public class CinqueFilosofi { public static void main (String args[]) { Semaphore sv[] = new Semaphore[5]; for (int i=0; i < 5; i++) sv[i]=new Semaphore(1); Filosofo fv[] = new Filosofo[5]; for (int i=0; i < 5; i++) fv[i]=new Filosofo(i,sv[(i+4)%5], sv[(i+1)%5]); for (int i=0; i < 5; i++) fv[i].start(); } } Sistemi Operativi P.Trunfio – R.Ortale