use*_*178 15 java multithreading tomcat memory-leaks servlets
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();
Nat*_*hes 17
是的,这是一个问题.如果您的代码启动非守护程序线程,那么这些线程将继续工作,直到它们退出其run方法.即使其他一切都完成了,旧的JVM也会在这些线程继续运行的时候徘徊.如果启动一个新实例,那么您可能会遇到旧线程仍在与新实例创建的线程一起工作的情况.
需要设计任务,以便他们能够响应中断(而不是吃异常并继续进行,这就是你的例子所示).这意味着检查当前线程上的中断标志,并以一种有用的方式捕获InterruptedException,允许任务中断其工作,并在需要时重置中断的标志.ExecutorService实现有一个shutdownNow方法,它将中断当前任务.
确保执行程序关闭,您可以在ServletContextListener中处理它.
| 归档时间: | 
 | 
| 查看次数: | 53918 次 | 
| 最近记录: |