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

    [java] dati condivisi dai thread

    dovrei permettere l'accesso ad un intero oggetto, da parte di un solo thread alla volta....qualcuno sa dirmi come posso farlo?

  2. #2
    Devi implementare la concorrenza tra i vari thread
    Questo è un sempio di implementazione di una classe che rappresenterebbe una risorsa condivisa tra più thread, ci sono altre classi però tutto sommato i punti fondamentali si capiscono

    codice:
    //Classe che rappresenta la risorsa
    class Risorsa{
        private final int MAX = 2; //massimo di utenti che usano la risorsa contemporaneamente
        private int contatore = 0; //utenti che usano la risorsa
        
                
        public synchronized  void accesso(){
            //controllo se ci sono gia' due processi che utilizzano la risorsa
            while (contatore == MAX){
                try {
                    wait();  //se la risorsa è occupata metto gli altri thread in attesa
                }
                catch(InterruptedException e){
                    System.out.println("Errore nel wait di accesso");
                }
            }
            //ho preso la risorsa quindi incremento il numero di utenti che la stanno usando
            contatore++;   
        }         
            
        public synchronized void libero(){
            //ho terminato l'utilizzo della risorsa quindi diminuisco il contatore e risveglio
            //eventuali utenti in attesa di usarla.
            contatore--;
            if (contatore < MAX)
                notifyAll();  //il thread attuale finisce di usare la risorsa quindi "sveglia" tutti gli altri thread
        }
    }
    Ti faccio notare che i metodi di una classe condivisa per fare concorrenza tra più thread devono contenere la parola synchronized .

    Ciao.
    Si può vincere o perdere, l'importante è vincere o perdere da uomini...

    Neverland - Il mio Forum

  3. #3
    grazie mille per l'aiuto, ti pongo un altra domanda per evitare di sporcare il codice, prima di procedere, ma dovrei aver capito...
    la mia classe da proteggere ha un numero elevato di metodi,
    ha senso invocare il metodo accesso() all'inizio di ogni metodo(sempre della classe da "proteggere"), e alla fine di ogni metodo invocare il metodo libero()?

  4. #4
    Dipende com'è la classe, non puoi postare un po' di codice così ti so dare magari una risposta più precisa. :master:

    Ciao.
    Si può vincere o perdere, l'importante è vincere o perdere da uomini...

    Neverland - Il mio Forum

  5. #5
    non posso postarlo perchè è lunghino, lo ho uppato qui se vuoi dare un occhio...

    http://www.design-officine.com/download/Database.zip


    il codice è un pò incasinato ma la logca è che a quella classe deve accedere un solo thread alla volta, non solo a un metodo ma a tutti i metodi della classe....
    quindi se ogni metodo passa prima dal metodo accesso(), resterà in attesa se qualcuno sta già usando la classe, o mi sfugge qualcosa?

  6. #6
    Ah, ora ho capito, sta cosa non serve! La parola synchronized serve appunto per questo, se un thread è all'interno di uno dei metodi indicati con questa parola chiave nessun altro thread può utilizzare un qualsiasi metodo della stessa classe che abbia anch'esso la parola synchronized nell'intestazione. Per riassumere, se la tua classe ha 10 metodi tutti synchronized e un thread accede ad uno di questi metodi nessun altro thread può accedere a nessuno degli altri metodi finchè questo in esecuzione non ha terminato.

    Ho visto il codice, il tuo metodo tutto sommato va bene però il synchronized come ti ho detto va messo per sicurezza a tutti i metodi della classe che indicano la risorsa condivisa. E poi una piccola correzione tecnica, questo non risveglierà mai niente perchè entra nell'if solo se occupato è true, cosa che dal tuo codice è impossibile. Tra l'altro questo if è inutile...
    codice:
    public synchronized void libero(){
       occupato = false;
       if (occupato){
          notifyAll();
       }
    }
    direi meglio così
    codice:
    public synchronized void libero(){
       occupato = false;
       notifyAll();
    }
    Per vedere se funziona ti conviene fare delle prove e vedere come si comportano i vari thread, magari aggiungendo dei System.out.println() con del testo qua e là così da capire dove e come viene eseguito il codice.

    Ciao.
    Si può vincere o perdere, l'importante è vincere o perdere da uomini...

    Neverland - Il mio Forum

  7. #7
    ok ora è tutto chiaro...
    pensavo che veniva bloccato l'accesso solo al metodo non a tutta la classe, quindi così è tutto molto semplice.
    grazie mille

  8. #8
    Di nulla!

    Ciao.
    Si può vincere o perdere, l'importante è vincere o perdere da uomini...

    Neverland - Il mio Forum

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.