Apache Tomcat多次说:
Web应用程序[/ MyServlet]似乎已启动名为[pool-61-thread-2]的线程,但未能将其停止 . 这很可能造成内存泄漏 .
这有危险吗? servlet应该能够处理10.000个请求/天 . 完成后如何关闭线程?
class Worker {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
private final int threadNumber;
Worker(
CountDownLatch startSignal,
CountDownLatch doneSignal,
int threadNumber
){
this.startSignal = startSignal;
this.doneSignal = doneSignal;
this.threadNumber = threadNumber;
}
public String[][] getSomeStrArrArr() {
String[][] isRs = new String[8][20];
String[][] inRs = new String[8][20];
String[][] iwRs = new String[8][20];
try {
startSignal.await();
if (threadNumber == 1) {
// get String[][] result for thread number 1
isRs = getIS(erg1, erg2, request);
}
if (threadNumber == 2) {
// get String[][] result for thread number 2
inRs = getIN(search_plz, request);
}
if (threadNumber == 3) {
// get String[][] result for thread number 3
iwRs = getIW(erg1, erg2, request);
}
doneSignal.countDown();
} catch (InterruptedException ex) {
System.out.println(
"Thread number "+threadNumber+" has been interrupted."
);
}
if (threadNumber == 1) {
return isRs;
}
if (threadNumber == 2) {
return inRs;
}
if (threadNumber == 3) {
return iwRs;
}
return null;
}
public Callable<String[][]> getSomeCallableStrArrArr(){
return new Callable<String[][]>() {
public String[][] call() throws Exception {
return getSomeStrArrArr();
}
};
}
}
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<String[][]>> set = new HashSet<Future<String[][]>>();
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(3);
for (int i=1;i<=3;i++) {
Worker worker = new Worker(startSignal,doneSignal,i);
Callable<String[][]> callable =
worker.getSomeCallableStrArrArr();
Future<String[][]> future = pool.submit(callable);
set.add(future);
}
startSignal.countDown();
try {
doneSignal.await();
1 回答
是的,这是一个问题 . 如果您的代码启动非守护程序线程,那么这些线程将继续工作,直到它们退出其run方法 . 即使其他一切都完成了,旧的JVM也会在这些线程继续运行的时候徘徊 . 如果启动一个新实例,那么您可能会遇到旧线程仍在与新实例创建的线程一起工作的情况 .
需要设计任务,以便他们能够响应中断(而不是吃异常并继续进行,这就是你的例子所示) . 这意味着检查当前线程上的中断标志,并以一种有用的方式捕获InterruptedException,允许任务中断其工作,并在需要时重置中断的标志 . ExecutorService实现有一个shutdownNow方法,它将中断当前任务 .
Here's an example of how to stop a thread using interruption .
确保执行程序关闭,you can handle this in a ServletContextListener .