Comments
Description
Transcript
Java_Threads (4)
Operating Systems applied computer science urbino worldwide campus Java threads 4 Java threads (4) Primitive di sincronizzazione il package java.util.concurrent emanuele lattanzi isti information science and technology institute Operating Systems Java threads 4 1/15 applied computer science urbino worldwide campus Motivazioni • Nasce dall’osservazione, che java, nonostante prevedesse dei meccanismi per la programmazione concorrente sin dalla nascita, da allora non ha fatto significativi passi in avanti in questo campo • I meccanismi che mette a disposizione sono piuttosto primitivi e rigidi; necessità di astrazione emanuele lattanzi isti information science and technology institute 2/15 1 Operating Systems applied computer science urbino worldwide campus Java threads 4 J2SE 6.0 e la Programmazione Concorrente • Package di principale interesse – java.util.concurrent • framework per la scrittura di codice concorrente – java.util.concurrent.locks • framework con gli usuali strumenti a supporto dei problemi di competizione e cooperazione – java.util.concurrent.atomic • classi wrapper che offrono operazioni atomiche grazie ad istruzioni del tipo TestAndSet, qui chiamate CompareAndSet (CAS), aggiunte al supporto della JVM emanuele lattanzi isti information science and technology institute Operating Systems Java threads 4 3/15 applied computer science urbino worldwide campus I Lock: java.util.concurrent.locks.Lock Method Summary void lock() Acquires the lock. void lockInterruptibly() Acquires the lock unless the current thread is interrupted. Condition newCondition() Returns a new Condition instance that is bound to this Lock instance. boolean tryLock() Acquires the lock only if it is free at the time of invocation. boolean tryLock(long time, TimeUnit unit) Acquires the lock if it is free within the given waiting time and the current thread has not been interrupted. void unlock() Releases the lock. emanuele lattanzi isti information science and technology institute 4/15 2 Operating Systems applied computer science urbino worldwide campus Java threads 4 Le Variabili Condizione: java.util.concurrent.locks.Condit Method Summary ion void await() Causes the current thread to wait until it is signalled or interrupted. boolean await(long time, TimeUnit unit) Causes the current thread to wait until it is signalled or interrupted, or the specified waiting time elapses. long awaitNanos(long nanosTimeout) … void awaitUninterruptibly() Causes the current thread to wait until it is signalled. boolean awaitUntil(Date deadline) …. void signal() Wakes up one waiting thread. void signalAll() Wakes up all waiting threads. emanuele lattanzi isti information science and technology institute Operating Systems 5/15 applied computer science urbino worldwide campus Java threads 4 Implementazioni di Lock e Condition • java.util.concurrent.locks.Lock e java.util.concurrent.locks.Condition sono interfacce • java.util.concurrent.locks.ReentrantLo ck è una implementazione di lock rientranti – lo stesso thread può invocare più lock() senza bloccarsi • con il metodo factory Lock.newCondition() si ottiene una implementazione anonima delle variabili condizione emanuele lattanzi isti information science and technology institute 6/15 3 Operating Systems applied computer science urbino worldwide campus Java threads 4 Utilizzo degli oggetti Lock Lock l = una implementazione di Lock; l.lock(); try { regione critica sulla risorsa condivisa } finally { l.unlock(); } emanuele lattanzi isti information science and technology institute Operating Systems 7/15 applied computer science urbino worldwide campus Java threads 4 I Semafori: java.util.concurrent.Semaphore Constructor Summary Semaphore(int permits) Creates a Semaphore with the given number of permits and nonfair fairness setting. Method Summary void acquire(int permits) Acquires the given number of permits from this semaphore, blocking until all are available, or the thread is interrupted. int availablePermits() Returns the current number of permits available void release(int permits) Releases the given number of permits, … boolean tryAcquire(int permits) Acquires the given number of permits from this semaphore, only if all are available at the time of invocation. emanuele lattanzi isti information science and technology institute 8/15 4 Operating Systems applied computer science urbino worldwide campus Java threads 4 Buffer Circolare (1) • Implementiamo un buffer circolare di dimensione finita adatto ad essere utilizzato da molteplici thread • N.B. la classe ArrayBlockingQueue fornisce le medesime funzionalità • Utilizziamo – Lock – Variabili Condizione emanuele lattanzi isti information science and technology institute Operating Systems 9/15 applied computer science urbino worldwide campus Java threads 4 Buffer Circolare (2) import java.util.concurrent.locks.*; public class BufferCircolare { // attributi dell'oggetto private int buffer[]; private int first; private int last; private int numberInBuffer; private Lock lock = new ReentrantLock(); private final Condition notFull = lock.newCondition(); private final Condition notEmpty = lock.newCondition(); ... emanuele lattanzi isti information science and technology institute 10/15 5 Operating Systems applied computer science urbino worldwide campus Java threads 4 Buffer Circolare (3) //… public BufferCircolare(int length){ this.buffer = new int[length]; this.first = 0; this.last = 0; this.numberInBuffer = 0; } //… emanuele lattanzi isti information science and technology institute Operating Systems 11/15 applied computer science urbino worldwide campus Java threads 4 Buffer Circolare (4) //… public void put(int item) throws InterruptedException { lock.lock(); try { while (numberInBuffer == size) notFull.await(); last = (last + 1) % size; numberInBuffer++; buffer[last] = item; notEmpty.signal(); } finally { lock.unlock(); } } //… emanuele lattanzi isti information science and technology institute 12/15 6 Operating Systems applied computer science urbino worldwide campus Java threads 4 Buffer Circolare (5) } } //… public int get() throws InterruptedException { lock.lock(); try { while (numberInBuffer == 0) notEmpty.await(); first = (first + 1) % size ; numberInBuffer--; notFull.signal(); return buffer[first]; } finally { lock.unlock(); } emanuele lattanzi isti information science and technology institute Operating Systems 13/15 applied computer science urbino worldwide campus Java threads 4 Il Barbiere che dorme 1. In un negozio c’è un solo barbiere, una sedia da barbiere e n sedie per l’attesa. 2. Quando non ci sono clienti, il barbiere dorme sulla sedia. 3. Quando arriva un cliente, questo sveglia il barbiere se sta dormendo. 4. Se la sedia è libera e ci sono clienti, il barbiere fa sedere un cliente e lo serve. 5. Se un cliente arriva e il barbiere sta già servendo un cliente, si siede su una sedia di attesa se ce ne sono di libere, altrimenti se ne va. • Problema: programmare il barbiere e i clienti filosofi in modo da garantire assenza di deadlock emanuele lattanzi isti information science and technology institute 14/15 7 Operating Systems applied computer science urbino worldwide campus Java threads 4 Il Barbiere che dorme: una soluzione Tre semafori: • customers: blocca il barbiere in attesa dei clienti (contati da una variabile waiting), • barbers: blocca i clienti in attesa del barbiere, • mutex: per mutua esclusione. • Il barbiere esegue una procedura che lo blocca se non ci sono clienti; quando si sveglia, serve un cliente e ripete. • Ogni cliente prima di entrare nel negozio controlla se ci sono sedie libere; altrimenti se ne va. • Un cliente, quando entra nel negozio, sveglia il barbiere se sta dormendo. emanuele lattanzi isti information science and technology institute 15/15 8