Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312

    concorrenza classe readwritelock

    Salve a tutti,
    ho un problema sulla classe ReadWriteLock. Devo rendere l'accesso concorrente all'accesso degli elementi di un arraylist. Nel senso, da come ho capito posso creare un lock ed utilizzare wait e signal. Il mio problema è che se faccio una wait blocco l'intero thread ma devo fare in modo che se scrivo in una casella dell'arraylist blocco gli altri a leggere soltanto in quella casella.
    Come posso fare?

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

    Re: concorrenza classe readwritelock

    Originariamente inviato da lio.b
    ho un problema sulla classe ReadWriteLock. Devo rendere l'accesso concorrente all'accesso degli elementi di un arraylist.
    Dipende .... da cosa devi fare di preciso.

    Originariamente inviato da lio.b
    Nel senso, da come ho capito posso creare un lock ed utilizzare wait e signal.
    Beh, sì, possono centrare anche wait/signal nel senso che per ognuno dei 2 Lock forniti da ReadWriteLock puoi avere il suo Condition.
    Ma puoi anche solo lavorare a livello di "lock", non necessariamente a livello di "condition queue". Visto che tanto vuoi solo fornire una sincronizzazione su una lista volendo però offrire una maggior concorrenza per N lettori simultanei.

    Perché è a questo che serve ReadWriteLock. Nelle normali collezioni "synchronized" il lock è uno e unico e impedisce la sovrapposizione scrittore/scrittore (ed è giusto/necessario), scrittore/lettore (ed è giusto/necessario) ma pure lettore/lettore (ed è qui il punto dolente).
    A patto che solo uno scrittore per volta possa accedere in scrittura (escludendo altri lettori, ovviamente), se la scrittura garantisce, agli altri thread, una "visione" up-to-date dei dati modificati, perché poi N lettori (che magari hanno bisogno di dati differenti) si dovrebbero bloccare tra loro??
    Il problema del lock unico ed esclusivo è appunto questo. Con ReadWriteLock la mutua esclusione è tra N lettori e 1 scrittore. Non tra un lettore e un altro lettore!

    Originariamente inviato da lio.b
    Il mio problema è che se faccio una wait blocco l'intero thread ma devo fare in modo che se scrivo in una casella dell'arraylist blocco gli altri a leggere soltanto in quella casella.
    Come posso fare?
    No alt. Mica vorrai gestire un lock per ogni singola cella ....
    Al massimo potresti usare la tecnica del lock "striping".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    No alt. Mica vorrai gestire un lock per ogni singola cella ....
    Io intendevo proprio quello... Devo inserire file all'interno delle celle di un array list ed altri thread leggono questi file.Quindi vorrei evitare che se un thread sta scrivendo nella cella i-esima si debba bloccare un altro thread che sta leggendo il file nella cella i + 1. Che c'è di sbagliato? Ogni suggerimento è ben accetto.
    Il lock striping non ho idea di cosa sia. Mai sentito.

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da lio.b
    Io intendevo proprio quello...
    Dipende da quanti elementi hai ... 10? 20? Ok. Oppure 100? 1000? Allora no!

    Originariamente inviato da lio.b
    Il lock striping non ho idea di cosa sia. Mai sentito.
    Il "lock striping" è una tecnica usata da una delle nuove collezioni di Java 5, java.util.concurrent.ConcurrentHashMap.

    Una map ad accesso "veloce" (come HashMap o appunto ConcurrentHashMap) è basata su una "hash table" interna, che contiene un array di "bucket" e sotto ogni bucket ci può essere una lista linkata di entry.

    L'array dei bucket può essere anche molto grosso, dipende dal "carico" nella map ovviamente. In ConcurrentHashMap non c'è 1 lock per ogni bucket!! No, invece c'è un numero fisso e molto ridotto, per default 16 (ma si può configurare con l'apposito costruttore) di lock.
    Ogni lock "protegge" più di un bucket, con una logica matematica molto semplice:

    Il lock 0 protegge i bucket 0, 16, 32, 48, ....
    Il lock 1 protegge i bucket 1, 17, 33, 49, ....
    Il lock 2 protegge i bucket 2, 18, 34, 50, ....
    ....
    Il lock 15 protegge i bucket 15, 31, 47, 63, ....

    In pratica dato un indice nella lista dei bucket, il lock da usare è a: indice mod 16

    Con una map questo è generalmente molto efficace, perché si presuppone che le chiavi nella map siano ben "sparpagliate" tra i bucket (se il hashCode() è implementato bene) e quindi più thread (fino a 16 appunto) probabilmente accederanno a bucket differenti, senza causare impedimenti tra di loro. E ottenendo così una alta concorrenza!
    L'unico svantaggio è che per fare operazioni globali sulla map (es. un resize della lista dei bucket o un clear della map), necessita di acquisire tutti i lock. Ecco perché è bene che non siano tanti!

    Ora ... non so se il lock striping applicato ad una lista potrebbe andarti bene. Non hai specificato quanti thread sai (o presumi) che ci debbano essere, non hai specificato "cosa" devono fare i tuoi thread sulla lista (fanno tutti le stesse cose? leggono molto e scrivono poco? O il contrario?). Non hai specificato quanti elementi nella lista sai (o presumi) che ci debbano essere.
    Insomma, con così poche informazioni, non saprei cosa dirti di più e per me puoi fare un po' quello che vuoi ....
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    Ok, hai ragione, ho dato poche informazioni.
    Ho 2 thread, uno scrive un file immagine nell'array list e l'altro legge (in maniera temporizzata) per mostrare il file(immagine) in una JLabel.
    Non posso sapere quanti file ho ma all'incirca non credo siano più di 30...in base a quanto detto credi che sia logico implementare la prima soluzione? Perchè se le immagini fossero molte non conviene?
    Comunque, correggimi se sbaglio, secondo me ha più senso creare un'arraylist di readwriteclock per quanto dicevo nel post precedente, CONCORDI?
    Detto ciò, non è meglio usare shincronyzer anzichè readwriteclock?????
    Tanto avrò al più un lettore per ogni cella dell'array...

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da lio.b
    Ho 2 thread, uno scrive un file immagine nell'array list e l'altro legge (in maniera temporizzata) per mostrare il file(immagine) in una JLabel.
    Non posso sapere quanti file ho ma all'incirca non credo siano più di 30...
    Fammi capire, hai fatto tutta una serie di elucubrazioni così complicate, parlando di ReadWriteLock, wait, signal ecc... quando poi devi fare una cosa così semplice, banale e lineare???

    Hai un thread "produttore", che carica delle immagini, una per volta in sequenza, suppongo. E questo è ok. Dici che hai un thread di lettura che mostra immagini in modo "temporizzato". Già questo non servirebbe.

    Quello che ti serve è un banale Vector o in alternativa un ArrayList "wrappato" come synchronized list (con synchronizedList() di Collections). Il thread che produce immagini usa questa collezione synchronized solo per fare add() per aggiungere una immagine.

    Non ti serve un "thread di lettura". Usa javax.swing.Timer. Nell'evento del timer sei già nel contesto del EDT, puoi quindi accedere tranquillamente a qualunque componente della interfaccia (JLabel o quello che userai per visualizzare la immagine).
    Ad ogni evento del timer semplicemente cerchi di andare avanti come indice nella lista, eventualmente tornando all'inizio (se vuoi il "loop" delle immagini) se sei alla fine.

    È inutile fare discorsi su ReadWriteLock o qualunque altra "sofisticheria" se poi le tempistiche di scrittura nella lista e sopratutto di lettura dalla lista sono così alte che non frega niente a nessuno se viene usata una piccolissima frazione infinitesima di tempo per acquisire un lock giusto per aggiungere o leggere un oggetto ogni tanto!!!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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.