Forum » Programiranje » Java Singleton @Lock(LockType.WRITE)
Java Singleton @Lock(LockType.WRITE)
SasoS ::
Nisem najbolj domač v Javi, me pa zanima kako rešiti sledečo situacijo:
1. Imaš Singleton class, po EJB specifikaciji kontejner upravlja dostope iz več threadov, po defaultu so metode LockType.WRITE, razen če je anotirano drugače
2. imaš več metod, ki berejo podatke iz classa (recimo da metoda vrne nek private Map). Anotiraš LockType.READ zato ker je izvedba kratka in ker hočeš da več threadov bere hkrati iz map ki jih vračaš. Mape se tukaj ne bodo spreminjale.
3. imaš metodo reload(), ki osveži podatke iz baze in jih naloži v mapo. Metoda traja dalj časa zato ker mora prebrat vse podatke iz baze...metoda je @Schedule recimo na vsako uro.
Kako zagotovit čim večji concurrency?
Če reload() metodo anotiraš LockType.WRITE, potem je dostop do ostalih metod zaklenjen dokler se refresh ne dokonča. Recimo da ni pomembno, če kakšna read metoda dobi še staro mapo, refresh() metodo pa lahko narediš da najprej polni podatke v lokalno temp mapo, ki jo nakoncu izvajanja zamenjaš z class global mapo, ki jo vračajo read funkcije.
Problem je ta zadnji korak - za zamenjavo map, ko si že prebral podatke iz baze in da zamenjaš globalno mapo, ki jo vračajo read metode, bi načeloma moral upgradati LockType.WRITE. Dokler si podatke polnil v temp mapo, ni problem če se izvajajo read metode, na koncu pa za čas zamenjave mape rabiš exclusive lock.
Kako to narediti by-the-book? Poseben synchronized block? It v celoti na ConcurrencyManagementType.BEAN? Ker če interno znotraj classa kličeš drugo metodo, se lock ne upošteva (ker si že v containerju), če kličeš getBusinessObject() dobiš IllegalLoopbackException, ker si v READ locku:
If a loopback call occurs on a Singleton that holds a Read lock on the same thread ( but does not also hold a Write lock on the same thread ) :
• If the target of the loopback call is a Write method, a javax.ejb.IllegalLoopbackException must be thrown to the caller.
Kreirat timer ki bo po prebranih podatkih čez 1 sekundo klical drugo LockType.WRITE metodo in zamenjal staro mapo z novo? Sigurno obstaja boljši način...
1. Imaš Singleton class, po EJB specifikaciji kontejner upravlja dostope iz več threadov, po defaultu so metode LockType.WRITE, razen če je anotirano drugače
2. imaš več metod, ki berejo podatke iz classa (recimo da metoda vrne nek private Map). Anotiraš LockType.READ zato ker je izvedba kratka in ker hočeš da več threadov bere hkrati iz map ki jih vračaš. Mape se tukaj ne bodo spreminjale.
3. imaš metodo reload(), ki osveži podatke iz baze in jih naloži v mapo. Metoda traja dalj časa zato ker mora prebrat vse podatke iz baze...metoda je @Schedule recimo na vsako uro.
Kako zagotovit čim večji concurrency?
Če reload() metodo anotiraš LockType.WRITE, potem je dostop do ostalih metod zaklenjen dokler se refresh ne dokonča. Recimo da ni pomembno, če kakšna read metoda dobi še staro mapo, refresh() metodo pa lahko narediš da najprej polni podatke v lokalno temp mapo, ki jo nakoncu izvajanja zamenjaš z class global mapo, ki jo vračajo read funkcije.
Problem je ta zadnji korak - za zamenjavo map, ko si že prebral podatke iz baze in da zamenjaš globalno mapo, ki jo vračajo read metode, bi načeloma moral upgradati LockType.WRITE. Dokler si podatke polnil v temp mapo, ni problem če se izvajajo read metode, na koncu pa za čas zamenjave mape rabiš exclusive lock.
Kako to narediti by-the-book? Poseben synchronized block? It v celoti na ConcurrencyManagementType.BEAN? Ker če interno znotraj classa kličeš drugo metodo, se lock ne upošteva (ker si že v containerju), če kličeš getBusinessObject() dobiš IllegalLoopbackException, ker si v READ locku:
If a loopback call occurs on a Singleton that holds a Read lock on the same thread ( but does not also hold a Write lock on the same thread ) :
• If the target of the loopback call is a Write method, a javax.ejb.IllegalLoopbackException must be thrown to the caller.
Kreirat timer ki bo po prebranih podatkih čez 1 sekundo klical drugo LockType.WRITE metodo in zamenjal staro mapo z novo? Sigurno obstaja boljši način...
Spura ::
A kdo razen @Schedule sploh klice reload()? In zakaj rabis lock za zmenjavo mape, to je atomarna operacija?
SasoS ::
reload() kliče samo @Schedule.
Map je več, read metode pa niso čisto vedno atomarne, ker včasih delajo kak containsKey(). Najbolj čisto se mi zdi da bi za tisti trenutek zamenjave map imel exclusive lock.
OK, lahko bi tudi poenostavil read() metode da ima samo 1 atomic operacijo, ampak to bi pa že potem spet spreminjal arhitekturo.
Map je več, read metode pa niso čisto vedno atomarne, ker včasih delajo kak containsKey(). Najbolj čisto se mi zdi da bi za tisti trenutek zamenjave map imel exclusive lock.
OK, lahko bi tudi poenostavil read() metode da ima samo 1 atomic operacijo, ampak to bi pa že potem spet spreminjal arhitekturo.
Spura ::
Meni se to sploh ne zdi problem, ne razumem zakaj bi imel exclusive lock.
private transient Map<String, String> xxxx = .... public reload() { .... loadas iz baze... xxxx = loadedMap; } // ko uporabis ta map ga najprej spravis v lokalno spremenljivko public someFunction() { Map<....> local = xxxx; // zdej lahko izvajam vec operacij na konsistentni sliki podatkov if (local.containsKey()) { .... } }Tuki predpostavljam da teh map ne spreminjas, ampak jih vedno cele zamenjas.
Zgodovina sprememb…
- spremenil: Spura ()
Zimonem ::
Saj imaš napisan. Medtem ko menjaš referenco mape , zavržeš requeste. Na žalost. Drugo je pa če delaš fail safe tam imaš pa beleženje requests in potem resolvanje, ampak to ni hitro.
Spura ::
Ce imas vec kot eno mapo si naredi en class ki vsebuje vse mape ki jih loadas, tako da potem na koncu reloada zamenjas instanco tega classa, tako poskrbis da so vse mape zamenjane hkrati.
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [VB] datagridviewOddelek: Programiranje | 1938 (1321) | korenje3 |
» | [Java] Multi Client chat serverOddelek: Programiranje | 2511 (1782) | javaMaster |
» | Kako zaščitit podatke?!Oddelek: Programska oprema | 1760 (1591) | Jeronimo |
» | [Java] servlet - kako upload-at iz klienta v servletOddelek: Programiranje | 1728 (1634) | Fizikalko |
» | [JAVA]Branje podatkov tipa int, doubleOddelek: Programiranje | 3400 (3298) | BaRtMaN |