Java线程池,如何使用shutdownNow()立即停止长时间运行的线程?

时间:2016-03-07 19:44:53

标签: java multithreading threadpool legacy-code

我有一个使用Executors创建多个线程的主线程

input

每个线程都有长时间运行的作业(来自另一个团队的一些遗留代码)可能会持续数小时。

现在我想使用

从主线程关闭
td

我希望线程能够立即停止,我怎么能这样做?

在帖子中,说我们有这样的代码:

dragulaObject.on('drag', function(el, source) {
   $(source).find('input').attr('value', '');
});

}

现在我的问题是,即使我调用ExecutorService executor = Executors.newFixedThreadPool(4); ,正在运行的线程将运行到最后然后停止。我想知道如何停止和退出。

2 个答案:

答案 0 :(得分:1)

这确实是一个有点棘手的情况!

我们可以使用JDK以ThreadFactory形式提供的钩子,当关联的线程池创建一个运行旧任务的线程时,该钩子会被查询吗?如果是,那么为什么不让你的遗留代码在daemon线程中运行?我们知道当最后一个non-daemon线程退出时,JVM退出。因此,如果我们让线程池使用的每个线程来运行您的遗留任务作为守护程序线程,那么我们就有可能使shutdownNow()调用更具响应性:

public class LegacyCodeExecutorEx {
    public static void main(String[] args) throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(2, new DaemonThreadFactory());

        executor.submit(new LegacySimulator());
        Thread.sleep(1000);
        executor.shutdownNow();
    }

    static class LegacySimulator implements Runnable {
        private final AtomicLong theLong;
        LegacySimulator() {
            theLong = new AtomicLong(1);
        }
        @Override
        public void run() {
            for (long i = 10; i < Long.MAX_VALUE; i++) {
                theLong.set(i*i);
            }
            System.out.println("Done!");
        }
    }
    static class DaemonThreadFactory implements ThreadFactory {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName("Daemon Thread");
            t.setDaemon(true);
            return t;
        }
    }
}

如果您使用setDaemon(true)行,您会看到此代码要么立即响应主线程的退出(即non-daemon),要么花费自己的甜蜜时间来完成任务

让遗留代码运行的线程daemon线程成为可能吗?如果是的话,你可以尝试一下。

答案 1 :(得分:0)

您需要在function y = fcn(u, v) %#codegen y.a=innerplus(u.a,v.a); y.b=innerplus(u.b,v.b); y.c=innerplus(u.c,v.c); end function y=innerplus(u,v) y.x1=u.x1+v.x1; y.x2=u.x2+v.x1; end 对象实例化中包含一个标志,用于检查任务是否需要停止。

Runnable

Java中的线程以(相对)低级别运行。除了直接关闭整个JVM之外,手动强制停止线程的唯一方法是使用Java 1.0 / 1.1中的Deprecated行为,这几乎没有人希望您使用。