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

    [Java] Vector e synchronized

    Devo gestire delle collezioni di oggetti in un sistema Client-Server. Per farlo ho pensato di utilizzare dei Vector che sono già sincronizzati.

    Ora, il mio dubbio è proprio sulla sincronizzazione: da quello che avevo capito dallo studio se all'interno di una classe sono dichiarati dei metodi synchronized essi saranno mutualmente esclusi tra di loro cioè una volta che viene acquisito da un oggetto il lock dovuto al synchronized del metodo nessun altro metodo potrà esere invocato da nessun oggetto. E' così anche per i vector?

    In parole povere: le operazioni eseguite da thread differenti su Vector di oggetti diversi (e potenzialmente chiamati da metodi di classi diverse) sono mutualmente escluse?
    Chiedendo anche con il codice:
    codice:
    //THREAD1 esegue Vector<Oggetto1> es1= new Vector<Oggetto1>(); 
    es1.add(Oggetto1);  
    //THREAD2 esegue Vector<Oggetto2> 
    es2= new Vector<Oggetto2>(); es2.add(Oggetto2);  
    //il thread2 deve aspettare che l'operazione di 
    //add venga eseguita o l'esecuzione di queste due 
    //operazioni avviene "simultaneamente"?

  2. #2
    Il vector ti garantisce che le operazioni di scrittura e lettura siano esclusive da parte di un solo thread per volta. Le altre strutture dati non te lo garantiscono, quindi la risposta alla tua domanda è "si!".

    Sia ben chiaro che la sincronizzazione si riferisce esclusivamente alla struttura dati e non al suo contenuto.


  3. #3
    Il vector ti garantisce che le operazioni di scrittura e lettura siano esclusive da parte di un solo thread per volta. Le altre strutture dati non te lo garantiscono, quindi la risposta alla tua domanda è "si!". Sia ben chiaro che la sincronizzazione si riferisce esclusivamente alla struttura dati e non al suo contenuto.
    Allora io continuo a non capire una cosa, forse non sono stato chiaroo sono io confuso... Riporto da questa fonte [http://www.ateneonline.it/hyperbook/j_book/J1002.htm]:

    In Java tale meccanismo è stato automatizzato quanto più possibile; ogni istanza di qualsiasi oggetto ha associato un mutex. Quando un thread esegue un metodo che è stato dichiarato sincronizzato mediante il modificatore synchronized, entra in possesso del mutex associato all’istanza e nessun altro metodo sincronizzato può essere eseguito su quell’istanza fintanto che il thread non ha terminato l’esecuzione del metodo
    Invocando due metodi statici sincronizzati di una stessa classe da due thread diversi, essi verranno quindi eseguiti in sequenza mentre invocando un metodo statico e un metodo d’istanza, entrambi sincronizzati, di una stessa classe, essi verranno eseguiti contemporaneamente
    Nella classe vector i metodi che modificano la struttura dati (.get()/.remove()...) non sono sicuramente statici e quindi non ci dovrebbe essere mutua esclusione tra istanze differenti della classe (diversi oggetti Vector di diverse classi)..

    La mia paura, come si volevo scrivere sopra, è che l'esecuzione da parte di un thread di una istruzione su un deveterminato oggetto Vector (magari una scrittura molto lunga) blocchi l'esecuzione di un altra operazione su un altro Vector differente (magari in lettura).

    Stavo costruendo in alternativa una classe "Semaforo" di base, con due metodi sincronizzati p() e v() per poter gestire la differente sincronizzazione nelle diverse parti del programma. Istanziando oggetti Semaforo differenti sono sicuro che i diversi thread che eseguano una differente istanza di semaforo non si escludano a vicenda??
    Con la classe impostando un valore del semaforo elevato potrei permettere di eseguire letture multiple su una struttura dati come un ArrayList a differenza della lettura del Vector?

    Ecco un po' di codice del mio Semaforo
    codice:
    public class Semaforo{ 
    public int valore; 
    public String nome; 
    public int numThr;  
    
    public Semaforo(int val, String identif){     
    valore= val;     nome= identif;     numThr=0; 
    }  
    
    public Semaforo(String identif){     this(0,identif); }  
    
    //Metodo che ricerca di ottenere la risorsa condivisa 
    public synchronized void p(){     /
    /finche' non ci sono risorse condivise rimango in attesa     while (valore==0){         try{             
    wait();        
     }catch(InterruptedException e){}     
    }     
    //dato che e' disponibile una risorsa prendo un valore     
    valore--;     numThr++; 
    } 
    
    public synchronized void v(){     
    //rilascio la disponibilita' di una risorsa che puo' essere presa da altri     
    valore++;     numThr--;     
    //messaggio di notifica di rilascio della risorsa     
    notify(); 
    } 
    public String getNome(){     return nome; } 
    public int getNumThr(){     return numThr; } 
    public int getValore(){     return valore; } 
    public void setValore(int i){     valore= i; } }
    Sono stato un po' confusionario, scusatemi

  4. #4
    La mia paura, come si volevo scrivere sopra, è che l'esecuzione da parte di un thread di una istruzione su un deveterminato oggetto Vector (magari una scrittura molto lunga) blocchi l'esecuzione di un altra operazione su un altro Vector differente (magari in lettura).
    che intendi per "un altro Vector differente"? un altro oggetto?

  5. #5
    sì un altro oggetto vector.. come scrivevo nel primo messaggio:

    codice:
    //THREAD1 esegue Vector<Oggetto1> es1= new Vector<Oggetto1>(); 
    es1.remove(Oggetto1);  
    
    //THREAD2 esegue Vector<Oggetto2> es2= new Vector<Oggetto2>(); 
    es2.add(Oggetto2);  
    
    //il thread2 deve aspettare che l'operazione di add venga eseguita  
    //o l'esecuzione di queste due 
    //operazioni avviene "simultaneamente"?

  6. #6
    ah io davo per scontato tu ti riferissi ad un solo Vector con accesso simultaneo di due thread!

    Se due Thread diversi accedono a due Vector diversi non c'è problema! Possono leggere e scrivere contemporaneamente.

  7. #7
    Se hai due instanze diverse della stessa Classe ad esempio vector i metodi definiti in essa (a patto che non siano statici) non vengono eseguiti in maniera sincronizzata, ergo, se hai un vector1 su chiami una "get" e un vector2 su cui fai un "add" queste due operazioni possono essere tranquillamente essere eseguite in paralello essendo sia "get" che "add" metodi sincronizzati ma non statici.
    Se vuoi che tali operazioni siano mutualmente esclusive allora il metodo migliore è richiamarle all'interno di un blocco/metodo sincronizzato.

  8. #8
    Grazie mille a lancill e francesco, per le risposte!
    Allora avevo capito bene su Vector e sincronizzazione!!

    Per sviluppare la comunicazione tra client-server nel sistema che sto sviluppando ho utilizzato l'rmi ma per gestire i dati più importanti sul server principale e renderlo thread-safe ho utilizzato i vector.. Ne approfitto per chiedervi altre due dritte:
    - Questa combo rmi&vector (lavorare con gli oggetti remoti/gestione dei dati) mi garantisce un sistema Multi-thread (rmi) ma comunque thread-safe (dato che i dati condivisi sono memorizzati dentro il vector)!!??
    - Ho preferito così piuttosto che continue letture di dati su file, all'avvio del server legge dati necessari ai client e li memorizza in un vector e poi binda l'oggetto necessario che viene recuperato dai client.. Era meglio secondo voi un'altra struttura dati??

    Se vi interessa sapere un po' meglio di che cosa si tratta il progetto potete leggere qualche info su questo thread (troppo lungo e poco accativante che non ha avuto seguito, sicuramente sono io che sono veramente troppo prolisso: http://forum.html.it/forum/showthrea...readid=1514685)

    Grazie ancora, vediamo se c'è qualc'un altro che mi può dare delle indicazioni

  9. #9
    Originariamente inviato da GHoldenBoy
    - Questa combo rmi&vector (lavorare con gli oggetti remoti/gestione dei dati) mi garantisce un sistema Multi-thread (rmi) ma comunque thread-safe (dato che i dati condivisi sono memorizzati dentro il vector)!!??
    Bella domanda.... Sicuramente l'accesso al vector sarà Thread Safe il resto ovviamente no, quindi dire che il tuo programma (Server) sia Thread Safe solo perchè utilizza i vector per memorizzare i dati non è corretto.
    - Ho preferito così piuttosto che continue letture di dati su file, all'avvio del server legge dati necessari ai client e li memorizza in un vector e poi binda l'oggetto necessario che viene recuperato dai client.. Era meglio secondo voi un'altra struttura dati??
    Bè scegliere la struttura dati più congrua a memorizzare i dati di un programma nn è una cosa banale (basti pensare che quando facevo l'uni c'erano ben due esami sulle strutture dati) da snocciolare in un post.
    Sul fatto di memorizzare questi dati e non leggerli di continuto dal file bisogna anche stare attenti alla mole di dati che carichi in memoria. Ovviamente se sono pochi dati la cosa rende più veloce il programma, ma se tali dati sono molti e magari vengono duplicati tra i vari Thread che gestiranno i client la cosa andrebbe un pò rivista.

  10. #10
    Bella domanda.... Sicuramente l'accesso al vector sarà Thread Safe il resto ovviamente no, quindi dire che il tuo programma (Server) sia Thread Safe solo perchè utilizza i vector per memorizzare i dati non è corretto.
    Credevo che:
    - Rmi produce per ogni richiesta del Client thread separati (giusto?)
    - le richieste al massimo modificano una struttura dati vector su cui lavoreranno tutti i client
    e quindi pensavo che non ci fossero problemi..

    Ho altre situazioni particolari da gestire?

    Adesso devo vedere di lavorare per evitare fenomeni sulla duplicazione dei dati sul server per la gestione dei diversi client e osservare se la struttura dati che ho scelto e'migliore di molti accessi su un file di testo sul server, se hai/avete indicazioni io sono tutto orecchie !!

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 © 2025 vBulletin Solutions, Inc. All rights reserved.