Ultima modifica:
Buongiorno a tutti, sto riscontrando un problema con il seguente codice che sarebbe il Produttore e Consumatore con un buffer illimitato rappresentato dall'ArrayList gestito con i semafori e che dovrebbe essere Thread-Safe.
Ora, non so perché ma quando invoco leggi() in th2 mi fa partire l'eccezione, il che mi fa pensare che non abbia l'esclusività della risorsa nonostante abbia fatto l'acquire.
Il Produttore può scrivere all'infinito, ovviamente aggiungendo un dato alla volta, mentre il Consumatore ovviamente non può leggere se l'ArrayList è vuoto.
Qualcuno sa come risolvere questo grattacapo?
Grazie in anticipo per le risposte e buona giornata ( o buona serata se lo state leggendo di sera)
Ora, non so perché ma quando invoco leggi() in th2 mi fa partire l'eccezione, il che mi fa pensare che non abbia l'esclusività della risorsa nonostante abbia fatto l'acquire.
Il Produttore può scrivere all'infinito, ovviamente aggiungendo un dato alla volta, mentre il Consumatore ovviamente non può leggere se l'ArrayList è vuoto.
Qualcuno sa come risolvere questo grattacapo?
Java:
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class Risorsa {
private ArrayList<Integer> list = new ArrayList<>();
private Semaphore s0 = new Semaphore(1); // per scrivere nella list
Random rand = new Random(100);
public static void main(String [] args){
Risorsa risorsa = new Risorsa();
Thread th1 = new Thread(){
/***********************************************
Scrive un intero (risorsa condivisa) al
ritmo di uno ogni secondo
**********************************************/
@Override
public void run() {
System.out.println("Th1 : avvio...");
while(true){
System.out.println("Th1 : sta scrivendo...");
risorsa.scrivi();
System.out.println("Th1 : ha terminato la scrittura...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread th2 = new Thread(){
/***********************************************
Visualizza tutti i valori prodotti
(ognuno visualizzato una sola volta)
**********************************************/
@Override
public void run() {
System.out.println("Th2 : avvio...");
while(true){
System.out.println("Th 2: sta per leggere i valori...");
risorsa.leggi();
System.out.println("Th 2: ha terminato la lettura");
}
}
};
th1.start();
th2.start();
}
/*******************
Metodi
*******************/
void scrivi(){
try {
s0.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add(rand.nextInt(100));
System.out.println("Th1 : aggiunto ");
s0.release();
}
void leggi(){
//Cerca di acquisire il permesso di lettura
try {
s0.acquire();
} catch (InterruptedException e) {
System.out.println("?");
}
if (list.isEmpty()){//pre-rilascio
s0.release();
System.out.println("Nulla da leggere!");
}
else {
try{
list.forEach(it->{
System.out.println("\tHo letto : "+it);
list.remove(it);
});
}
catch (ConcurrentModificationException e){//Se non catturo l'eccezione va in errore
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
s0.release();
}
}
Grazie in anticipo per le risposte e buona giornata ( o buona serata se lo state leggendo di sera)