• Non ci sono risultati.

1 Programmazione in rete e laboratorio2002-03

N/A
N/A
Protected

Academic year: 2022

Condividi "1 Programmazione in rete e laboratorio2002-03"

Copied!
3
0
0

Testo completo

(1)

1

Programmazione in rete e laboratorio 2002-03

JAVA - Thread esempio Banca Alberto Martelli

Thread 2

Esempio da JAVA2 (secondo volume)

Abbiamo una classe Bank con un metodo transfer per trasferire denaro da un conto ad un altro.

Thread 3

class Bank

{ public Bank(int n, int initialBalance) { accounts = new int[n];

int i;

for (i = 0; i < accounts.length; i++) accounts[i] = initialBalance;

}

public void transfer(int from, int to, int amount) { if (accounts[from] < amount) return;

accounts[from] -= amount;

accounts[to] += amount;

}

private int[] accounts;

}

Thread 4

Supponiamo di creare un oggetto Bank e di creare più thread che eseguono il metodo tranfer su questo oggetto, per eseguire dei trasferimenti fra i conti della banca.

I thread possono interferire causando una variazione sul totale delle somme presenti in tutti i conti (che dovrebbe rimanere invariato).

Ad esempio, supponiamo che il conto i abbia una somma di 5000, e che vengano eseguiti due thread che trasferiscono in questo conto le somme di 1000 e 2000, rispettivamente.

I due thread dovranno eseguire ciascuno l'istruzione accounts[i] += amount;

Thread 5

Nella Java Virtual Machine l'istruzione accounts[i] += amount;viene realizzata con una sequenza di istruzioni elementari, che trasferiscono il valore di accounts[i]in un registro, lo incrementano e lo riportano in accounts[i].

Se un thread viene interrotto dall'altro thread mentre esegue questa sequenza di istruzioni, il risultato può essere sbagliato.

thread1 registro1 = 5000

thread1 registro1 = 6000 il thread 1 viene interrotto thread2 registro2 = 5000

thread2 registro2 = 7000

thread2 accounts[i] = 7000 il thread 1 riprende thread1 accounts[i] = 6000

Thread 6

Sincronizzazione

Per risolvere il problema è sufficiente dichiarare il metodo transfer synchronized. In questo modo solo un thread per volta lo potrà eseguire.

Quando un thread riesce ad acquisire il lock della banca e ad eseguire il metodo transfer, potrà procedere fino al termine del metodo senza che nessun altro thread possa interferire.

(2)

2

Thread 7

Cooperazione fra thread

Il metodo transfer non esegue il trasferimento se la somma presente sul conto di partenza è più bassa di quella che si vuole trasferire.

Lo vogliamo modificare in modo che, nel caso di somma insufficiente, il thread che lo esegue rimanga in attesa che la somma sul conto sia sufficiente per eseguire il trasferimento.

Il metodo può essere modificato come segue:

Thread 8

public synchronized void transfer(int from, int to, int amount) { try

{ while (accounts[from] < amount) wait();

accounts[from] -= amount;

accounts[to] += amount;

ntransacts++;

notifyAll();

}

catch(InterruptedException e) {}

}

Thread 9

Deadlock

Un programma che contiene più thread che eseguono il metodo transfer può andare in stallo (deadlock). Questo può succedere, ad esempio, se:

• tutti i thread sono in wait perché la somma da trasferire è troppo alta

• il metodo transfer esegue alla fine una notify invece della notifyAll. Il thread sbloccato dalla notify potrebbe non essere in grado di procedere, mentre con la notifyAll si potrebbe sbloccarne uno in grado di proseguire.

Thread 10

L’esempio è poco realistico perché la sincronizzazione viene fatta sul lock della banca, e quindi si può eseguire solo un trasferimento alla volta.

Vediamo un altro esempio in cui vengono introdotte anche le classi BankAccount.

Nella prima versione (BankTest) non c’è sincronizzazione.

La classe BankAccount contiene i metodi deposit e withdraw. Il metodo withdraw è booleano e restituisce false quando il saldo del conto non è sufficiente per fare il prelievo.

Per potere osservare gli effetti di una esecuzione concorrente di questi metodi, è stata introdotta una variabile temp ed è stata inserita una sleep nel metodo withdraw.

Thread 11

La classe Bank contiene un array di BankAccount ed un metodo transfer che esegue un trasferimento fra due conti della stessa banca.

Questo metodo esegue un prelievo dal primo conto ed un versamento nel secondo. Se il prelievo non è possibile, non fa niente.

Il main attiva diversi thread, ciascuno dei quali esegue un trasferimento fra due conti scelti a caso di una cifra scelta a caso.

Eseguendo più volte questo programma, si nota che spesso il programma funziona in modo scorretto perché la somma dei saldi di tutti i conti dalla banca è diversa all’inizio e alla fine dell’esecuzione.

Thread 12

Il programma può essere modificato (BankTestSynchr) dichiarando i due metodi deposit e withdraw di BankAccount come synchronized. Inoltre il metodo withdraw si mette in wait se il suo saldo non è sufficiente per il prelievo.

In questo caso la sincronizzazione è fatta sul lock di un BankAccount.

Due thread si devono sincronizzare solo se eseguono ambedue una operazione sullo stesso conto. Non c’è bisogno di sincronizzare la transfer di Bank.

(3)

3

Thread 13

Eseguendo questo programma si nota che spesso il programma non termina. Questo succede quando un thread rimane bloccato in wait nella withdraw di un conto, in attesa che ci sia una cifra sufficiente, e nessun altro thread esegue un versamento sullo stesso conto.

Questo comportamento è più probabile più è alta la soglia sulle cifre da trasferire.

Riferimenti

Documenti correlati

•  Per attivare il thread deve essere chiamato il metodo start() che invoca il metodo run() (il metodo run() non può essere. chiamato direttamente, ma solo

implementazione del concetto di monitor: un oggetto java è associato ad un mutex ricorsivo tramite il quale è possibile disciplinare gli accessi da parte di diversi thread allo

 La funzione DEVE ESSERE CHIAMATA su una variabile mutex che sia già bloccata e di proprietà del thread chiamante. In tal caso la funzione pthread_mutex_unlock sblocca la

▪ Assegnare memoria e risorse per la creazione di nuovi processi è oneroso; poiché i thread condividono le risorse del processo cui appartengono, è molto più con- veniente creare

 Wait (and act) for a single thread within a large group of

 Tale valore risulta disponibile al thread che effettua una pthread_join..

• Il metodo run della classe di libreria Thread definisce l’insieme di statement Java che ogni thread (oggetto della classe) eseguirà.. concorrentemente con gli

Come conferma l’ultima voce esemplificata, nel lessico della moda di questo dizionario sono attestati anche forestierismi (27, poco meno della metà del totale del lessico di