2011-09-15 8 views
7

Background:L'utilizzo di java.util.concurrent.Executor ferma tomcat l'arresto

ho bisogno di usare java.util.concurrent.Executor per serializzare l'esecuzione di codice legacy all'interno di un webservice.

Ho aggiunto una variabile membro, executor, alla classe WebService. Viene iniettato dall'esterno dal tralcio.

Il fagiolo esecutore è definito come tale:

versione
<bean id="riskValueEstimateUpdateExecutor" scope="singleton" 
     class="java.util.concurrent.Executors" 
     factory-method="newSingleThreadExecutor" /> 
  • Tomcat: versione 6.0.22
  • Java: quadro 1.6
  • molla: 2.5.5

Problema:

WS funziona come previsto. Lo abbiamo lanciato su un server Linux. Poi ci siamo resi conto che lo script di tomcat stop non poteva più interrompere il servizio.

Io uso kill -3 nell'istanza di tomcat. Nel dump di thread trovo queste righe:

"pool-2-thread-1" prio=10 tid=0xad637c00 nid=0xf37 waiting on condition [0xae882000..0xae883020] 
    java.lang.Thread.State: WAITING (parking) 
     at sun.misc.Unsafe.park(Native Method) 
     - parking to wait for <0xb453b710> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1925) 
     at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:358) 
     at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:946) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:906) 
     at java.lang.Thread.run(Thread.java:619) 

Come posso risolvere questo problema?

Se avete bisogno di ulteriori informazioni, si prega di suggerire.

risposta

8

Non è colpa né di Tomcat né di Spring. Devi solo spegnere correttamente ExecutorService. Aggiungere destroy-method in definizione di fagioli:

<bean id="riskValueEstimateUpdateExecutor" scope="singleton" 
    class="java.util.concurrent.Executors" 
    factory-method="newSingleThreadExecutor" destroy-method="shutdown"/> 

BTW singleton campo di applicazione è di default. Potresti anche considerare l'utilizzo del metodo shutdownNow(). Si noti inoltre che Spring fornisce un potente meccanismo task scheduling.

+0

è questo il corretto da utilizzare esecutori in tomcat/java/spring env? – Dejell

5

È necessario trovare un modo per chiamare shutdown quando il contesto di primavera viene arrestato: provare a utilizzare la proprietà destroy-method del bean e impostarlo su shutdown. Qualcosa del genere:

<bean id="riskValueEstimateUpdateExecutor" scope="singleton" 
     class="java.util.concurrent.Executors" 
     factory-method="newSingleThreadExecutor" destroy-method="shutdown" /> 
+0

la tua risposta è altrettanto buona! Vorrei poter accettare anche la tua risposta. –

+0

come si imposta la quantità dei fili? – Dejell

+0

Utilizzare un esecutore diverso: newSingleThreadExecutor è (per definizione) un singolo thread. Checkout java.util.concurrent.Executors per alternative. – Femi