Quando si utilizza una connessione al database locale del thread, la chiusura della connessione è necessaria quando il thread esiste.Come forzare un thread Java per chiudere una connessione al database locale del thread
Ciò che posso fare solo se riesco a sovrascrivere il metodo run() del thread chiamante. Anche quella non è una soluzione eccezionale, dal momento che al momento dell'uscita, non so se una connessione è mai stata aperta da quel thread.
Il problema è in realtà più generale: come forzare un thread per chiamare un metodo di finalizzazione di un oggetto thread-locale quando esce.
ho guardato le fonti di Java 1.5 e ha scoperto che la cartina di filo viene impostato su null, che finirà per causare la garbage collection di chiamare finalizzare(), ma io non voglio contare sulla spazzatura collettore.
seguito di esclusione sembra inevitabile fare in modo che una connessione al database viene chiusa:
@Override
public void remove() {
get().release();
super.remove();
}
dove release() chiude la connessione al database, se è stato aperto. Ma non sappiamo se il thread abbia mai usato questo thread-local. Se get() non è mai stato chiamato da questa discussione, poi c'è tutto uno spreco di energie qui: ThreadLocal.initialValue() sarà chiamato, una mappa verrà creato su questo thread, ecc
-
ulteriori chiarimenti e esempio secondo commento di Thorbjørn:
java.lang.ThreadLocal è un tipo di fabbrica per un oggetto che è destinato a un thread. Questo tipo ha un getter per l'oggetto e un metodo factory (tipicamente scritto dall'utente). Quando viene chiamato il getter, chiama il metodo factory solo se non è mai stato chiamato prima da questo thread.
Utilizzo di ThreadLocal consente a uno sviluppatore di associare una risorsa a un thread anche se il codice del thread è stato scritto da una terza parte.
Esempio: Dire che abbiamo una risorsa Tipo chiamato MyType e vogliamo avere uno e solo uno per thread.
Definire nella classe utilizzando: statica ThreadLocal privato resourceFactory = new ThreadLocal() { @Override protetta MyType initialValue() {return new MyType(); }}
Usa nel contesto locale in questa classe: pubblico someMethod void() { risorsa MyType = resourceFactory.get(); resource.useResource(); }
get() può chiamare initialValue() solo una volta nel ciclo di vita del thread chiamante. A questo punto un'istanza di MyType viene creata un'istanza e associata a questo thread. Le chiamate successive a get() da questo thread si riferiscono nuovamente a questo oggetto.
L'esempio classico di utilizzo è quando MyType è un formattatore di testo/data/xml non sicuro per il thread.
Tuttavia, tali formattatori di solito non devono essere rilasciati o chiusi, le connessioni database fanno e io sto usando java.lang.ThreadLocal per avere una connessione database per thread.
Il modo in cui lo vedo, java.lang.ThreadLocal è quasi perfetto per quello. Quasi perché non c'è modo di garantire la chiusura della risorsa se il thread chiamante appartiene a un'applicazione di terze parti.
Ho bisogno del tuo cervello scudieri: estendendo java.lang.ThreadLocal sono riuscito a legare una connessione al database per ogni thread, per il suo uso esclusivo - tra cui le discussioni che non posso modificare o override. Sono riuscito a fare in modo che le connessioni si chiudano nel caso in cui il thread muoia su un'eccezione non rilevata.
In caso di uscita filo normale, il garbage collector chiude la connessione (perché MyType sostituisce il finalize()). In realtà succede abbastanza velocemente, ma questo non è l'ideale.
Se fosse per me, non ci sarebbe stato un altro metodo sul java.lang.ThreadLocal:
protected void release() throws Throwable {}
Se questo metodo esisteva java.lang.ThreadLocal, chiamato da JVM su qualsiasi thread di uscita/morte, quindi nel mio override di esso potrei chiudere la mia connessione (e il redentore sarebbe arrivato a Sion).
In assenza di tale metodo, sto cercando un altro modo per confermare la chiusura. Un modo che non si baserà sulla garbage collection JVM.
Grazie
Si prega di aggiungere un codice minimale che mostri ciò che descrivi. Preferibilmente eseguibile. –
Aggiunto un po 'di codice. Spero che questo spieghi uno dei problemi. –
Bene, no. Si prega di creare un esempio funzionale minimo. –