Thread replayReqProducerThread=new Thread(new AdjustmentReplayRequestProducer(...);
replayReqProducerThread.start();
public class AdjustmentReplayRequestProducer implements Runnable{
public void run() {
while(true){...}
} }
以上代码希望在整个context中创建单例的Producer,不停地从database获取数据,放入队列,供消费者获取。但是部署到Websphere后,每次重启application后,都会多处一个Producer。原因是停止Webapplication时,由于该Thread没有纳入到Spring Context或任何其他Websphere管理的容器中,所以没有被销毁。
正确的做法是:1)由Spring管理的ThreadPool来创建该Thread
<bean id="replayProducerTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1"/>
<property name="maxPoolSize" value="1"/>
<property name="queueCapacity" value="1"/>
</bean>
replayProducerTaskExecutor.execute(new AdjustmentReplayRequestProducer(...));
2)在代码中加入
while(true){
if (Thread.currentThread().isInterrupted()) {
logger.info("producerTask is interrupted, will exit ...");
break; } ...
}
Thread.sleep(retrieveFcstAdjmtFromDBInterval);
} catch (InterruptedException e) {
logger.info("error occured: ", e);
Thread.currentThread().interrupt();
}
因为WebSphere在Stop application时,会stop Spring contxt.
com.ibm.ws.runtime.component.ApplicationMgrImpl AUDIT WSVR0217I: Stopping application: ruby-ae-replay_war
com.ibm.ws.webcontainer.webapp INFO com.ibm.ws.webcontainer.webapp.WebApp log SRVE0292I: Servlet Message - [ruby-ae-replay_war#ruby-ae-replay.war]:.Closing Spring root WebApplicationContext
Spring 会调用replayProducerTaskExecutor的destroy的this.executor.shutdownNow()
ThreadPoolExecutor的shutdownNow中有interruptWorkers
for (Worker w : workers) w.interruptIfStarted();->t.interrupt();
整个流程过后,该Produer会退出loop 循环。进而被回收