2009-02-10 8 views
108

Una delle prime cose che ho imparato sullo sviluppo di Java EE è che non dovrei generare i miei thread all'interno di un contenitore Java EE. Ma quando arrivo a pensarci, non ne conosco il motivo.Perché i thread di spawning nel contenitore Java EE sono scoraggiati?

Puoi spiegare chiaramente perché è scoraggiato?

Sono sicuro che la maggior parte delle applicazioni aziendali hanno bisogno di un qualche tipo di job asincroni come demoni di posta elettronica, le sessioni inattive, posti di lavoro di pulizia ecc

Quindi, se davvero non si dovrebbe generare discussioni, qual è il modo corretto per farlo Quando necessario?

+4

compiti asincroni si realizza utilizzando la messaggistica JMS e MDB. –

+5

Questo problema dovrebbe presto diventare un ricordo del passato una volta [JSR 236] (http://jcp.org/en/jsr/detail?id=236) implementato nei contenitori. – letmaik

+4

Si è sconsigliato perché ogni secondo thread deve essere creato e gestito dal contenitore, in modo che il thread abbia accesso alle altre risorse aziendali. Con Java EE7, esiste un modo standard e corretto per creare thread in un ambiente aziendale. Usando Concurrency Utils, si garantisce che il nuovo thread venga creato e gestito dal contenitore, garantendo che tutti i servizi EE siano disponibili. Esempio [qui] (http: // stackoverflow.it/questions/3212255/java-ee-specifica-e-multi-threading/19404307 # 19404307) –

risposta

79

È sconsigliato perché tutte le risorse all'interno dell'ambiente devono essere gestite e potenzialmente monitorate dal server. Inoltre, gran parte del contesto in cui viene utilizzato un thread è in genere collegato al thread di esecuzione stesso. Se si avvia semplicemente una propria discussione (che credo che alcuni server non consentono nemmeno), non può accedere ad altre risorse. Ciò significa che non è possibile ottenere un InitialContext e fare ricerche JNDI per accedere ad altre risorse di sistema, ad esempio Factories e origini dati di JMS Connection.

Ci sono modi per farlo "correttamente", ma dipende dalla piattaforma utilizzata.

The commonj WorkManager is common for WebSphere and WebLogic as well as others

More info here

And here

po duplica anche this one da questa mattina

UPDATE: Si prega di notare che questa domanda e risposta si riferiscono allo stato di Java EE nel 2009, le cose sono migliorati da allora!

+1

_non è possibile ottenere un InitialContext e fare ricerche JNDI per accedere ad altre risorse di sistema come Factories e origini dati di JMS Connection. Ho un'app che funziona attorno all'iniezione dell'origine dati all'avvio dei thread, ma potrei dover ripensare questo approccio. .. – rjohnston

+6

C'è ora un modo standard e corretto per creare discussioni con l'API Java EE core. Usando Concurrency Utils, si garantisce che il nuovo thread venga creato e gestito dal contenitore, garantendo che tutti i servizi EE siano disponibili. Esempi [qui] (http://blog.chris-ritchie.com/2013/09/simple-concurrency-example-with-wildfly.html) e [qui] (http: //blog.chris-ritchie. it/2013/10/managed-thread-factory-example-in-wildfly.html) –

+0

@ChrisRitchie grazie per il suggerimento. se solo JBoss AS/IBM ha supportato Java EE 7 ... :-( – asgs

1

Non ho mai letto che è scoraggiato, tranne dal fatto che non è facile da fare correttamente.

È una programmazione piuttosto di basso livello e, come altre tecniche di basso livello, si dovrebbe avere una buona ragione. La maggior parte dei problemi di concorrenza può essere risolta in modo molto più efficace utilizzando i costrutti integrati come i pool di thread.

+7

è infatti vietato dalle specifiche. –

+0

http://java.dzone.com/articles/5-quick-points-about-threads – newday

11

Il motivo per cui non è necessario generare i propri thread è che questi non saranno gestiti dal contenitore. Il contenitore si prende cura di molte cose che uno sviluppatore inesperto può trovare difficile da immaginare. Ad esempio cose come il pool di thread, il clustering, i ripristini di crash vengono eseguiti dal contenitore. Quando inizi una discussione potresti perderne alcuni. Inoltre, il contenitore consente di riavviare l'applicazione senza influire sulla JVM su cui viene eseguita. Come sarebbe possibile se ci fossero fili fuori dal controllo del contenitore?

Questa è la ragione per cui sono stati introdotti servizi timer J2EE 1.4. Vedere l'articolo this per i dettagli.

+1

JSR 236 ha aggiunto funzionalità per supportare i thread spawn in Java EE 7 e versioni successive. Vedi [questa risposta fratello di Chris Ritchie] (http://stackoverflow.com/a/19404453/642706). –

2

Non c'è un vero motivo per non farlo. Ho usato Quarz con Spring in una webapp senza problemi. Può essere utilizzato anche il framework di concorrenza java.util.concurrent. Se implementi la tua gestione dei thread, imposta i thead su deamon o usa un proprio gruppo thread deamon per loro in modo che il contenitore possa scaricare la tua webapp in qualsiasi momento.

Ma attenzione, il fagiolo ambiti sessione e richiesta non funzionano in discussioni deposto le uova!Anche l'altro codice prodotto su ThreadLocal non funziona immediatamente, è necessario trasferire da sé i valori ai thread generati.

2

È sempre possibile indicare al contenitore di avviare i materiali come parte dei descrittori di distribuzione. Questi possono quindi eseguire qualsiasi attività di mantenimento che è necessario eseguire.

Seguire le regole. Un giorno l'avrai fatto :)

0

Una ragione per cui ho trovato se si generano alcuni thread in EJB e quindi si tenta di scaricare o aggiornare il bean che si verificherà nei problemi. C'è quasi sempre un altro modo di fare qualcosa in cui non hai bisogno di una discussione, quindi basta dire NO.

32

Per bean, non è solo scoraggiato, è espressamente vietato dalla specification:

Un bean enterprise non deve usare filo primitive di sincronizzazione per sincronizzare esecuzione di molteplici istanze.

e

Il fagiolo di impresa non deve tentare per gestire le discussioni. Il bean enterprise non deve tentare di avviare, arrestare, sospendere o riprendere una discussione o su modificare la priorità o il nome di un thread. Il bean enterprise non deve tentare per gestire i gruppi di thread.

La ragione è che gli EJB sono pensati per operare in un ambiente distribuito. Un EJB potrebbe essere spostato da una macchina in un cluster a un'altra. I fili (e le prese e altre strutture vietate) rappresentano un ostacolo significativo a questa portabilità.

+3

Java EE7 Concurrency Utils fornisce un modo corretto per creare thread in un ambiente aziendale Esempi [qui] (http: // blog.chris-ritchie.com/2013/09/simple-concurrency-example-with-wildfly.html) e [qui] (http://blog.chris-ritchie.com/2013/10/managed-thread-factory -example-in-wildfly.html) –

+1

@Dan Puoi spiegarmi perché un Filo sarebbe un ostacolo significativo alla portabilità di spostare un EJB da una macchina in una custer a un'altra? – Geek

2

I thread sono vietati nei contenitori Java EE in base ai progetti. Si prega di fare riferimento allo blueprints per ulteriori informazioni.

5

Concorrenza Utilità per Java EE

Ora c'è uno standard, e il modo corretto per creare filettature con l'API nucleo Java EE:

Utilizzando concorrenza Utils, ci si assicura che il nuovo thread sia creato e gestito dal contenitore, garantendo che tutti i servizi EE siano disponibili.

Esempi here