Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    8

    Sincronizzazione ed Hashtable

    Salve a tutti ragazzi.. Sto realizzando un piccolo progetto per l'università che consiste di un banale sistema di ecommerce client/server che non utilizza database ma salva il tutto su file e gestisce in modo sincronizzato le transazioni sugli oggetti ma permette anche l'accesso concorrente se si tratta di oggetti diversi.. La prima cosa che ho pensato di fare è usare un hashtable (che poi serializzerò su file per salvare i dati) che ad ogni chiave associa un oggetto prodotto da me creato che contiene i metodi per le operazioni di vendita che vanno a modificare le quantità. Tali metodi chiaramente definiti synchronized. Così mi sembrava a primo acchitto di poter risolvere tutti i miei problemi.. Infatti, a meno che non dico grandi cavolate, in questo modo dovrebbero sincronizzarsi i singoli oggetti prodotto...
    Ora viene il bello.. Ciò che ignoravo, non conoscendo benissimo l'hashtable, è che non esiste una cosa di questo tipo per accedere direttamente agli oggetti contenuti al suo interno:

    (Prodotto)h[chiave].metodo_mio_oggetto..

    E quindi dovrei fare una cosa del genere:

    Prodotto p = (Prodotto)h.get(chiave);
    p.metodo_mio_oggetto;
    p.add(chiave,p);

    Ma così tutta la mia bella sincronizzazione è vana.. perchè se un thread arriva fino alla seconda riga di questo codice, viene messo in attesa, un altro riesce ad eseguire tutte e tre le righe.. quando il primo thread continua l'esecuzione mi sovrascrive tutto.. Ma non posso nemmeno mettere il blocco synchronized lì intorno perchè dovrei toglierlo dall'oggetto prodotto ma soprattutto così farei un lock su tutto l'hashtable.. e non sui singoli prodotti...

    Come potrei risolvere questo arcano ? Cosa mi consigliate ? Cambiare contenitore ? L'hashtable per me era appetibile per il semplice fatto della ricerca in O(1).. Dato che ogni volta che un client modifica o compra un prodotto devo notificarlo a tutti gli altri client, ogni volta dovrei fargli scorrere un ipotetico vettore o array che sia per ritrovare gli oggetti modificati ed aggiornarli e non mi sembra una cosa molto efficiente..

    Grazie mille in anticipo..

    PS:Vedendo le differenze tra hashtable e hashmap ho visto che sostanzialmente l'hashtable è sincronizzato e l'hashmap no.. ma che vantaggi mi porta il fatto che sia già sincronizzato se poi le operazioni di modifica non posso farle direttamente ?

  2. #2
    Utente di HTML.it L'avatar di Pastore12
    Registrato dal
    Oct 2008
    Messaggi
    1,051
    Un momento, aspetta un attimo..

    Prodotto p = (Prodotto)h.get(chiave);
    p.metodo_mio_oggetto;
    p.add(chiave,p);

    L'ultima operazione, quanto meno, non è necessaria! una volta che estrai un oggetto dalla Hashtable (così come da un vettore, uno Stack, un ArrayList...) e lo modifichi, non devi inserirlo nuovamente nella Hashtable! La struttura dati mantiene solo il riferimento a p, non una sua copia.
    "Ethics are to me something private. Whenever you use it as an argument for why somebody_else should do something, you’re no longer being ethical, you’re just being a sanctimonious dick-head"
    Linus Torvalds

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    8
    Grazie mille pastore.. quindi fare

    Prodotto p = (Prodotto)h.get(chiave);
    p.metodo_mio_oggetto;

    equivalrebbe all'ipotetico:

    (Prodotto)h[chiave].metodo_mio_oggetto

    che io pensavo non si potesse fare ?
    A questo punto quindi se metodo_mio_oggetto è definito come synchronized nella struttura dati Prodotto, nessun altro thread potrà richiamare quello o altri metodi synchronized mentre c'è già un thread dentro, giusto ?

    Scusate se faccio domande banali o se sembra che mi rispondo da solo ma sono argomenti nuovi per me e per quanto mi possa documentare, soprattutto sul multithreading penso ci sia un'alta possibilità di fare cavolate senza accorgersene specialmente all'inizio..

  4. #4
    Utente di HTML.it L'avatar di Pastore12
    Registrato dal
    Oct 2008
    Messaggi
    1,051
    Se dichiari synchronized un metodo d'istanza della classe Prodotto (cioè un metodo non statico), allora il risultato è che viene gestita l'esecuzione contemporaneamente di due o più chiamate a quel metodo per quello stesso oggetto.

    vedi: http://java.sun.com/docs/books/tutor.../syncmeth.html

    Quindi a questo punto.. ho un po' le idee confuse..
    Tu devi gestire le chiamate contemporanee su uno stesso prodotto.. quindi il fatto che un prodotto sia contenuto in una Hashtable non ti è di nessun aiuto..

    Supponiamo che il prodotto abbia un solo metodo setPrezzo(). Se dichiari syncronized tale metodo, il problema è risolto.

    Se invece un oggetto prodotto ha più metodi concorrenti da gestire.. dichiarare ciascuno syncronized non basta. Penso che dovresti creare una sorta di semaforo..

    Ciao!
    "Ethics are to me something private. Whenever you use it as an argument for why somebody_else should do something, you’re no longer being ethical, you’re just being a sanctimonious dick-head"
    Linus Torvalds

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    8
    mmm... Sulla pagina che mi hai linkato, che tral'altro avevo già letto, quasi all'inizio c'è scritto:

    First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

    E da quello che il mio inglese non eccellente mi lascia capire dice che "quando *un* thread sta eseguendo un metodo sincronizzato per un oggetto, tutti gli altri thread che invocano *metodi sincronizzati* per lo stesso oggetto si bloccano"..

    A me in questo caso serve solamente che non acceda + di 1 thread alla volta ad uno stesso oggetto e logicamente questo deve accadere per tutto il ciclo di modifica dell'oggetto, dalla lettura alla riscrittura...

    La mia classe Prodotto è così strutturata:

    public class Prodotto {
    private String descrizione;
    private int quantita;
    private double prezzo;

    public Prodotto (String descrizione, int quantita, double prezzo) {}

    public Prodotto (int quantita, double prezzo) {}

    public Prodotto (String descrizione, double prezzo) {}

    public Prodotto (double prezzo) {}

    public synchronized int getDisponibilita () {}

    public synchronized boolean acquista (int quantita) {}

    public synchronized void vendi (int quantita) {}
    }

    Ho tolto il codice per non rendere il messaggio troppo corposo..
    Ora io ho un Hashtable con tanti prodotti..
    e ci lavoro in questo modo:

    Prodotto p = (Prodotto) h.get(codice);
    p.vendi(quantita);

    Pensi che in questo modo, per questi requisiti sia comunque necessario utilizzare i semafori ? Mi spiegheresti dov'è che potrei incontrare problemi ?

  6. #6
    ma che è il progetto del bongiovanni? ma lol

    fine ot

  7. #7
    comunque anche io sto avendo problemi di sincronizzazione...non riesco a impostare i lock solo su una singola riga della hash table...ho usato una reference

    Product=tavola_hash.get(id)

    a questo punto utilizzo i metodi sincronizzati di Product però c'è qualcosa che non va in quanto il suo metodo sincronizzato può essere eseguito da più thread allo stesso istante(ho messo una stampa e una sleep all'interno del metodo e la stampa viene visualizzata anche quando il primo thread sta eseguendo la sleep)...probabilmente dichiaro Product nel posto sbagliato e nel modo sbagliato...

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