Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    thread che si alternano

    Salve raga devo fare un esercizio con i thread dove c'è bisogno che i thread si alternino,siccome non sono per niente bravo a gestire sti thread ancora, per fare capire a chi legge l'ho semplificato parecchio con una situazione analoga qui sotto.Il mio problema è che non riesco a fare alternare la stampaUNO con la stampaDUE ,invocate dai rispettivi thread t1 e t2 .Di sicuro è na cavolata per chi è pratico ma io è da ieri che ci sbatto la testa e niente.
    fra 20 giorni ho esame aiutooo


    codice:
    
    
    public class RisorsaSuCuiLav<T> {
    
    	private Lock lock = new ReentrantLock();
    	private final Condition  condizDiBloccoStampaUNO = lock.newCondition();
    	private final Condition  condizDiBloccoStampaDUE= lock.newCondition();
    	
    	
    	public RisorsaSuCuiLav() {
             
    
    	}
    	
    	public void stampaUNO{
        
    		lock.lock();
    		
    		try{
                            System.out.println("QUESTA è LA STAMPA UNO");
    			
    		     }
    
                          catch (Exception e) {
    				// TODO: handle exception
    			   }	
    
    			
    			finally
    			{
    				lock.unlock();
    			}
    		
    	}
    	
    	
    
    	public void stampaDUE(){
        
    	lock.lock();
    
    		
    		try{
    	              System.out.println("QUESTA è LA STAMPA DUE");
                       }			
    			
    			   catch (Exception e) {
    			
    			   }		
    
    		
    		   finally
    			{
    				lock.unlock();
    			}
    	
    	}
    	
    }

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254

    Re: thread che si alternano

    Originariamente inviato da valeriAsus
    Salve raga devo fare un esercizio con i thread dove c'è bisogno che i thread si alternino,siccome non sono per niente bravo a gestire sti thread ancora, per fare capire a chi legge l'ho semplificato parecchio con una situazione analoga qui sotto.Il mio problema è che non riesco a fare alternare la stampaUNO con la stampaDUE ,invocate dai rispettivi thread t1 e t2 .
    Hai già visto l'esempio di BoundedBuffer presente nella documentazione javadoc di Condition .... vero?

    Ecco, immagina che quel buffer sia di lunghezza max 1, avrai che l'unica sequenza di operazioni effettive (il "vero" lavoro compiuto dal metodo, insomma) possibile è proprio: inserisci - estrai - inserisci - estrai - inserisci - ...ecc...

    Ovviamente tu non dovrai fare una "coda", cioè non dovrai ricevere o restituire oggetti e quindi nemmeno avere un array che fa da buffer. Ma il concetto è quello!

    Ti servono quindi 2 Condition e una variabile di stato che dice, pensalo nel senso che vuoi, se "pieno" o "vuoto" (0 o 1 oppure "stampa uno" o "stampa due").

    Pensaci ...
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    guarda ti posto l'esercizio che volevo fare:
    inserire in una risorsa (arraylist) delle stringhe di un array. come puoi vedere nel main. Dividendo il lavoro tra due tread di tipo1 ,predisposti a fare un solo inserimento e poi cedere il lock al thread t2 per stampare tutto l'array list .Diciamo che qualcosa sono riuscito a fare solo che non funziona bene perchè non mi stampa tutti e 40 le celle e va in loop.. Gli puoi dare un occhiata

    codice:
    public class ThreadDiTipoUNO extends Thread{
    
    	private int inizio;
    	private  int fine;
        private String  array[];
        RisorsaSuCuiLav buffer;
    	
    	public ThreadDiTipoUNO(int i , int f , String a[], RisorsaSuCuiLav r) {
          inizio=i;
          fine=f;
    	 array=a;
    	 buffer=r; 
    	}
        
        
    	public void run(){
    		
    		try{
    			
    		while(inizio<fine){
    			buffer.immetti(array[inizio]);
    			inizio++;
    		}
    		
    		}catch (Exception e) {
    			// TODO: handle exception
    		}
    		
    	}
    	
    	
    }
    
    public class ThreadDiTipoDUE extends Thread{
    
    
       
        RisorsaSuCuiLav buffer;
    	
        public ThreadDiTipoDUE( RisorsaSuCuiLav r) {
      	 buffer=r; 
      	}
    	
        public void run(){
        	
        	buffer.stampa();
        
        }
    
    
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class RisorsaSuCuiLav<T> {
    
    	private Lock lock = new ReentrantLock();
    	private final Condition  condizDiBloccoImmiss = lock.newCondition();
    	private final Condition  condizDiBloccoStampa= lock.newCondition();
    
    	private int ins;
    	
    	
    	ArrayList<T> buffer=new ArrayList<T>();
    
    	public RisorsaSuCuiLav() {
         ins=0;
        
    	}
    	
    	public void immetti(T ri){
    		
    		
    		lock.lock();
    		
    		try{//1tr
    			
    			    if(ins==1)
    			         condizDiBloccoStampa.signal();
    			    
    		     while(ins==1)   
    
    		    	 try{//2tr
                     condizDiBloccoImmiss.await();
    				   }//2tr
    			      catch (Exception e) { }	
    
    			     
    			      buffer.add(ri);
    
    			      
    			      
    			      ins++;
    			      
    		}//1tr
    			
    			finally
    			{
    				lock.unlock();
    			}
    		
    	}
    	
    	
    
    	public void stampa(){
          //invocato da thread di tipo2
    		lock.lock();
    
    		
    		try{//1tr
    			
                 while(true){
    
                        	 while(ins == 0){ 	   
    			        
                        		 condizDiBloccoStampa.await();   
    			              }           
                        	 
    
                        	  Iterator<T>  it=buffer.iterator();
        			    	  
        			    	  while(it.hasNext()   ){
        			    		  
        			    		T element = it.next();
    
        			    		  System.out.print(" "+element);
        			    		  
        			    	  }
        			    	  System.out.println();
        			    	  
                        	 
                      ins = 0;               
                             condizDiBloccoImmiss.signal(); 
                             
                 }			
    	
    		
    		}	
    			   catch (Exception e) {
    				// TODO: handle exception
    			   }		
    
    		
    		   finally
    			{
    				lock.unlock();
    			}
    	
    	}
    	
    }
    
    
    public class MainProvaThread {
    
    	
    	
    	public static void main(String[] args) {
    		
    	    String array[]=new String[40];
    	    array[0]="1";
    	    array[1]="2";
    	    array[2]="3";
    	    array[3]="4";
    	    array[4]="5";
    	    array[5]="6";
    	    array[6]="7";
    	    array[7]="8";
    	    array[8]="9";
    	    array[9]="10";
    	    
    	    array[10]="11";
    	    array[11]="12";
    	    array[12]="13";
    	    array[13]="14";
    	    array[14]="15";
    	    array[15]="16";
    	    array[16]="17";
    	    array[17]="18";
    	    array[18]="19"; 
    	    array[19]="20"; 
    	    
    	    array[20]="21";
    	    array[21]="22";
    	    array[22]="23";
    	    array[23]="24";
    	    array[24]="25";
    	    array[25]="26";
    	    array[26]="27";
    	    array[27]="28";
    	    array[28]="29";
    	    array[29]="30";
    	    
    	    array[30]="31";
    	    array[31]="32 ";
    	    array[32]="33";
    	    array[33]="34";
    	    array[34]="35";
    	    array[35]="36";
    	    array[36]="37";
    	    array[37]="38";
    	    array[38]="39";
    	    array[39]="40";
    	    
    		RisorsaSuCuiLav<String> buffer=new RisorsaSuCuiLav<String>(); 
    
    		ThreadDiTipoUNO  t1[]=new ThreadDiTipoUNO[2];
    		
    	   int inizio=0;
           int fine=array.length/2;
           
               for(int i=0 ; i<t1.length ; i++){
    
            	   t1[i]=new ThreadDiTipoUNO(inizio,fine,array,buffer);
            	   t1[i].start();
            	   
                        inizio=fine;
            	        fine=inizio+fine;
               }
    	  
               ThreadDiTipoDUE  t2=new ThreadDiTipoDUE(buffer);
               t2.start();
               
               
    	}//chiusura main
    
    }

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da valeriAsus
    inserire in una risorsa (arraylist) delle stringhe di un array. come puoi vedere nel main. Dividendo il lavoro tra due tread di tipo1 ,predisposti a fare un solo inserimento e poi cedere il lock al thread t2 per stampare tutto l'array list .
    Innanzitutto il codice, per come l'hai postato, è davvero ben poco leggibile. Non so se per questioni di copia/incolla ma comunque ti suggerisco di migliorare la cosa, almeno in futuro (per te e per postare sul forum).
    Specialmente per le indentazioni vedo che ci sono tab mescolati a spazi. Io personalmente configuro gli IDE/editor che uso affinché salvino i sorgenti mettendo solo spazi e mai mettendo "hard" tab. Gli hard tab nei sorgenti mi irritano assai ....

    Veniamo ora alle questioni tecniche.

    1) ThreadDiTipoUNO mi pare corretto come logica, ed è anche chiaro cosa fa: Prende una porzione di un array e la passa al buffer elemento per elemento.

    2) RisorsaSuCuiLav l'hai definita come classe "generica" ma in ThreadDiTipoUNO la usi come "raw type". Non è proprio il massimo. Hai 2 possibilità per migliorare:
    a) Rendi ThreadDiTipoUNO anch'essa generica (la logica del lavoro lo permette). Cioè diventa ThreadDiTipoUNO<T> e riceverà un T[] e un RisorsaSuCuiLav<T>
    b) Se ti interessa che lavori solo con String, allora fai solo in modo che riceva RisorsaSuCuiLav<String>.

    3) Quello che non mi è chiaro è la logica a cui stavi pensando per RisorsaSuCuiLav. Quello che hai mostrato ora infatti mi ha un po' spiazzato rispetto a quanto avevi accennato all'inizio.
    Tu vuoi che ThreadDiTipoDUE invochi 1 volta sola buffer.stampa() per stampare tutto l'array.

    Ma scusa (ora viene la domandona): come fa RisorsaSuCuiLav a "sapere" quando hai riempito il buffer con tutti i dati per poter permettere a stampa() la stampa?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    guarda lascia stare la struttura ..perchè l'ho fatta cosi per fare prove non è niente di serio...scusa magari per la fretta non mi sono spiegato bene:

    vorrei far stampare dal secondo thread tutto il buffer dopo ogni inserimento da parte del primo ,ossia

    -immissione nel buffer di 1
    -stampa di tutto il buffer : 1

    -immissione nel buffer di 2
    -stampa di tutto il buffer : 1 2
    ... e cosi via

    Non pensare molto alla traccia perchè sto solo cercando di capire il meccanismo, con esercizi tristi creati da me per disperazione

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da valeriAsus
    vorrei far stampare dal secondo thread tutto il buffer dopo ogni inserimento da parte del primo ,ossia

    -immissione nel buffer di 1
    -stampa di tutto il buffer : 1

    -immissione nel buffer di 2
    -stampa di tutto il buffer : 1 2
    ... e cosi via
    Ok quindi la stampa non è di tutto alla fine degli inserimenti (che è una cosa). Ma ho capito: la stampa è di tutto quello che hai accumulato fino a quel momento (che è un'altra cosa, più facile ed adesso spiego).

    Ed è anche ben chiaro (perlomeno a me) che vuoi l'alternanza tra inserimento e stampa. Cioè ad un inserimento può solo seguire una stampa.

    Bene: allora innanzitutto il ArrayList è ok e giusto. Il Lock ti serve, ovviamente e ti servono anche 2 Condition. Quello a cui devi prestare attenzione è la "condizione" da testare.
    Nota che quello che stai facendo non è tecnicamente una "coda" ma riprendendo quello che dicevo nella mia prima risposta, il bloccaggio/sospensione dei thread è concettualmente esattamente come se avessi una coda (es. quel BoundedBuffer nel javadoc) di lunghezza 1.

    Ti basta usare un "flag" booleano, ad esempio:

    private boolean inserito;

    Se inserito è false, allora permetti l'inserimento (il test in immetti non deve far eseguire il await() ) ma impedisci la stampa (il test in stampa fa eseguire il await() ).

    Al contrario, quando inserito è true, allora impedisci l'inserimento (in immetti deve restare in await() ) ma permetti la stampa (il test in stampa non fa eseguire il await() ).

    Ti assicuro che non è difficile. A parte che nel tuo caso hai un ArrayList in cui inserire e a parte che in stampa hai quel ciclo esterno perenne (perché la invocazione di stampa è una sola) .... per il resto grosso modo la struttura/concetto è proprio quella di quel BoundedBuffer di esempio.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  7. #7
    ti ringrazio tantissimo cmq curiosità se volessi impostare sempre lo stesso esercizio con un timer ,potrei fare qualcosa per far si che xun un tot di secondi viene fatta immissione e dopo viene rilasciato il lock alla stampa e cosi via..?

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da valeriAsus
    potrei fare qualcosa per far si che xun un tot di secondi viene fatta immissione e dopo viene rilasciato il lock alla stampa e cosi via..?
    Qui dovresti precisare perché si può interpretare e pensare in vari modi:

    1) Se vuoi che tra un immetti() e l'altro passi del tempo, allora semplicemente dove invochi immetti() (es. in un ciclo) metti un Thread.sleep(nnn) in mezzo.

    2) Se vuoi che dopo l'inserimento effettivo nella lista passi del tempo prima di dare il "signal" per la stampa, allora metti un sleep tra il add e il signal (quindi dentro il buffer, questo però terrebbe "impegnato" il thread inseritore).

    3) Se vuoi che per un certo periodo di tempo si possano fare solo immetti() (quante più sono possibili in quel periodo) e finito questo periodo venga fatta una stampa e poi il periodo per gli immetti() inizi di nuovo ... beh, si può fare di certo anche questo ma diventa un pochino più complesso (io stesso dovrei ragionarci su come farlo).

    Se intendevi altro ... precisa.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  9. #9
    3)
    Vorrei che per un certo periodo di tempo si possano fare solo immetti() (quante più sono possibili in quel periodo) e finito questo periodo venga messo in await il thread che immette e venga avviato il thread che stampa... e cosi via. Mi piacerebbe sapere come si fa ,non che mi serve ma penso che potrebbe essere una cosa utile

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.