java中断线程

时间:2013-08-22 18:57:59

标签: java

我有一种情况,我正在使用一个Thread,她调用一个会执行多个进程的方法,我需要使用一个“取消”按钮,你必须在其中停止该线程,我不能使用:“while “,以验证它已被取消,因为它在此过程中没有循环。

例如:

    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            controller = new FirstEtapaController();
            execProcess();              
            return null;
        }
    };
    new Thread(task).start();

通话方法

   private void execProcess() {
   Thread thread = new Thread(new Runnable() {

        public void run() {
    getController().execMhetod();
    refreshTable();
        }
    });
    thread.start();
    thread.join();
};
是的,我需要停止这个过程,即使“ExecMethod”已经在运行,也需要几分钟,所以我必须停止它并且不必等他完成以便其他人不会继续。

记住这个过程将使用我的DAO进行迭代。

4 个答案:

答案 0 :(得分:2)

唯一的方法(表现良好的方式)是在生成的线程中添加逻辑点以检查中断状态。您可以选择使用内置的Thread.interrupt()机制,或者使用某种形式的线程安全变量(AtomicBoolean?)或某种形式的信号量来添加自己的逻辑。

如果使用Thread.interrupt(),则子进程在遇到某些条件时会抛出InterruptedException,如Thread.wait()和其他需要同步的方法或使用java.util.concurrent。*类。

无论如何,您将需要(应该已经)处理线程中的InterruptedExceptions,但是您可能需要在子进程中定期“检查”以查找中断状态(可以使用{ {1}})

值得一读Handling InterruptedException in Java

答案 1 :(得分:1)

如果您使用ExecutorService而不是原始线程,则最终会有许多其他方法/杠杆来控制您的线程,其中一个是shutdownAll(),它使用Thread.interrupt()杀死你的线程并让你通过isTerminated()

检查线程状态

答案 2 :(得分:0)

您的用户界面无需等待工作线程完成,因此请不要过于担心。

唉,由于实现不好,不推荐使用Thread.destroy()和Thread.stop()。我不认为有一个好的&#34; sig-kill&#34; Java线程的替代类型。如果重要的话,你将不得不重新编码工人以检查某种中止标志。否则,只是让它浪费一点CPU。 (&#34;你不能取消保存 - 我已经完成了它!&#34;,实际上)

答案 3 :(得分:0)

是否可以取消任务实际上取决于其实施。通常它会间歇性地检查标志是否应该继续。

您可以自己实现这样的标志,以及设置它的方法:

private volatile boolean shouldStop;

public void cancel() {
    shouldStop = true;
}

@Override
public void run() {
    while (!shouldStop) {
        // do work
    }
}

但线程已经带有一个标志:中断的标志。虽然它不一定用于取消线程,但通常将其用于此目的。实际上,标准ExecutorService实现将尝试通过中断它们来取消它们的线程。

除了几个阻塞方法(将线程置于BLOCKEDWAITING状态的方法)将在线程中断时抛出InterruptedException,此时它们变为{{ 1}}再次。这是以前使用布尔标志的方法无法实现的。

因此,使用中断以允许取消任务是更好的方法。而且你不再需要那个cancel()方法:

RUNNABLE

作为奖励,任何了解您的线程的代码都知道如何取消它。包括标准@Override public void run() { while (!Thread.currentThread().isInterrupted()) { // do work } } 实现。

在捕捉ExecutorService时应小心,因为这样做会清除中断的旗帜。建议在捕获异常时始终恢复被中断的标志,这样客户也知道是时候停止做他们正在做的事情了。

InterruptedException

要取消主题,您只需保留对private BlockingQueue<Integer> queue; @Override public void run() { while (!Thread.currentThread().isInterrupted()) { try { Integer id = queue.take(); // blocking method // do work } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } 对象的引用,并在其上调用Thread

interrupt()

但更优雅的方法是通过Thread thread = new Thread(new InterruptibleTask()); thread.start(); // some time after : thread.interrupt(); 对象密切关注您的任务(而不是它运行的特定线程)。您可以将FutureRunnable包裹在Callable中来完成此操作。

FutureTask

RunnableFuture<Void> task = new FutureTask<>(new InterruptibleTask(), null); new Thread(task).start(); // some time after : task.cancel(true); // true indicating interruption may be used to cancel. 是控制任务的关键。它允许您等待其完成,并可选择接收计算任务的值:

Future

如果您有多个任务(甚至只有一个),则值得使用ExecutorService:

try {
    String value = future.get(); // return value is generically typed String is just as example.
} catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // since future.get() blocks
} catch (ExecutionException e) {
    logger.log(Level.SEVERE, "Exception on worker thread", e.getCause()); // the ExecutionException's cause is the Exception that occurred in the Task
}