Problema programmazione concorrente

di il
4 risposte

Problema programmazione concorrente

Salve ragazzi, sono nuovo nel forum quindi mi presento, sono uno studente al 2o anno di ing.informatica e sto affrontando l'esame di sistemi operativi, sto svolgendo esercizi sulla programmazione concorrente, qualcuno mi può aiutare a risolvere i miei problemi con un codice con Lock e Condition.
Grazie anticpatamente


Qui la spiegazione dell'esercizio.
Una sala, in grado di ospitare fino a 30 persone, contiene un televisore con 8 canali. La sala è frequentata daun insieme di persone che vi si recano per guardare la TV in compagnia. Ogni persona effettua
periodicamente le seguenti operazioni:
1) sceglie a caso il canale C che vuole guardare (con C compreso tra 1 e ;
2) entra nella sala; finché la sala è piena, attende in ordine FIFO che si liberi un posto per entrare.
Dopo essere entrato nella sala:
· se nessuno sta guardando la TV, cambia il canale su C e prosegue con la visione;
· se il canale trasmesso è già uguale a C, prosegue con la visione;
· se infine il canale trasmesso è diverso da C, e qualcuno lo sta guardando, si mette in attesa fino a
quando il canale diventa uguale a C; al termine dell’attesa prosegue con la visione;
3) guarda il canale C per un tempo compreso tra 30 e 300 secondi;
4) esce dalla sala: prima di uscire, se nessuno sta più guardando il canale C, cambia il canale del
televisore in quello per cui è in attesa il maggior numero di persone.
Non si tenga conto della possibilità di starvation. Si modellino in Java le persone attraverso dei Thread e si
implementino due soluzioni che riproducano il funzionamento del problema sopra descritto utilizzando:
1. la classe Semaphore del package java.util.concurrent
2. gli strumenti di mutua esclusione e sincronizzazione del package java.util.concurrent.locks.
Si scriva infine un main d'esempio che, facendo uso di una delle due soluzioni precedenti, inizializzi 100
Il problema che mi da è che quando fa la wait il Thread, mi solleva una eccezione IllegalMonitorStateException che non riesco a risolvere

4 Risposte

  • Re: Problema programmazione concorrente

    Il problema e' banale:

    hai fatto la notify o la wait su un oggetto mentre non sei ancora dentro una synchronize() su quell'oggetto.

    Cioe, devi avere:
    
    ...
    synchronize(object) {
        object.wait();
    }
    ...
    synchronize(object) {
        object.notify();
    }
    
    
  • Re: Problema programmazione concorrente

    Non sto usando i synchronize, sto usando Lock e Condition, vorrei che qualcuno guardi il codice, non riesco proprio a rendermi conto da solo dell'errore
    Eccoli
    package esercizio.tvLC;
    
    import java.util.LinkedList;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Sala {
    private TVLC tv;
    private LinkedList<Thread> ll=new LinkedList<>();
    final int MAX=30;
    private int inside=0;
    private Lock l;
    private Condition c;
    
    public Sala(){
    	tv=new TVLC();
    	l=new ReentrantLock();
    	c=l.newCondition();
    }
    
    public void entra()throws InterruptedException{
    	l.lock();
    	try{
    	ll.addLast(Thread.currentThread());
    	while(inside>=MAX && Thread.currentThread()!=ll.getFirst()){
    		c.await();
    	}
    	ll.removeFirst();
    	inside++;
    	}
    	finally{l.unlock();}
    }
    
    public void esci()throws InterruptedException{
    	l.lock();
    	try{
    	inside--;
    	c.signalAll();
    	}
    	finally{l.unlock();}
    }
    
    public TVLC getTv(){
    	return tv;
    }
    }
    
    CLASSE TVLC
    package esercizio.tvLC;
    
    import java.util.concurrent.locks.*;
    
    public class TVLC {
    	final int NUM_CHANNEL=8;
    	private Lock l=new ReentrantLock();
    	private Condition [] c;
    	private int numSpett=0, canale=0;
    	private int [] waitChannel=new int [8];
    	
    	public TVLC(){
    		c=new Condition[NUM_CHANNEL];
    		for(int i=0; i<c.length; i++ )
    			c[i]=l.newCondition();
    	}
    	
    	public void iniziaVisione(int channel) throws InterruptedException{
    		l.lock();
    		try{
    		if(numSpett==0){
    			canale=channel;
    			numSpett++;
    		}
    		else if(canale==channel){
    			numSpett++;
    		}
    		else{
    			waitChannel[channel]++;
    			while(canale!=channel)c[channel].await();
    			waitChannel[channel]--;
    			numSpett++;
    		}
    		}
    		finally{l.unlock();}
    	}
    	
    	public void fineVisione()throws InterruptedException{
    		l.lock();
    		try{
    		numSpett--;
    		if(numSpett==0){
    			int ch=maxWaiting();
    			canale=ch;
    			c[canale].signalAll();
    		}
    		}finally{
    		l.unlock();}
    	}
    
    	private int maxWaiting() {
    		// TODO Auto-generated method stub
    		int max=0;
    		for(int i=1; i<waitChannel.length;i++)
    			if(waitChannel[i]>waitChannel[max])max=i;
    		return max;
    	}
    
    }
    CLASSE PERSONA
    package esercizio.tvLC;
    
    import java.util.Random;
    import java.util.concurrent.TimeUnit;
    
    public class Persona extends Thread{
    	Sala s;
    	TVLC tv;
    	Random r=new Random();
    public Persona(Sala s1){
    	s=s1;
    	tv=s.getTv();
    }
    
    public void run(){
    	while(true){
    		try {
    			int c=r.nextInt(tv.NUM_CHANNEL);
    			s.entra();
    			tv.iniziaVisione(c);
    			guarda(c);
    			System.out.println(getName() + " sta guardando canale "+ c);
    			tv.fineVisione();
    			s.esci();
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    		}
    		
    
    	}
    }
    
    private void guarda(int c) throws InterruptedException {
    	// TODO Auto-generated method stub
    	System.out.println(getName() + " sta guardando canale "+ c);
    	TimeUnit.SECONDS.wait(r.nextInt(270)+30);
    }
    }
    Ed il main di test
    package esercizio.tvLC;
    
    public class Test {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Sala s=new Sala();
    		Persona [] p=new Persona[100];
    		for(int i=0; i<p.length; i++)
    			p[i]=new Persona(s);
    		for(int i=0; i<p.length; i++)
    			p[i].start();
    	}
    
    }
    
  • Re: Problema programmazione concorrente

    L'errore e' ESATTAMENTE quello che ti ho indicato SENZA CONOSCERE nemmeno il codice!!!!!!!!

    Ti basta leggere il log! E il codice che hasi scritto!
  • Re: Problema programmazione concorrente

    Ho trovato, quella wait va usata SOLO con i metodi synchonized, se uso lock e condition va usata la Thread.sleep() , sostituendo infatti funziona
Devi accedere o registrarti per scrivere nel forum
4 risposte