java中的中断线程

java中的中断线程,java,Java,我使用一个线程,她调用一个方法来执行多个进程,我需要使用一个“取消”按钮来停止线程,我不能使用“while”来验证它是否被取消,因为它在这个进程中没有循环 例: 也就是说,我需要停止这个过程,即使“ExecMethod”已经运行了,也需要几分钟的时间,所以我必须停止它,不必等待他完成,这样其他人就不会继续了 记住这个过程将使用我的DAO进行迭代。唯一的方法(行为良好的方法)是在生成的线程中添加逻辑点,以检查中断状态。您可以选择使用内置的Thread.interrupt()机制,或者使用某种形式的

我使用一个线程,她调用一个方法来执行多个进程,我需要使用一个“取消”按钮来停止线程,我不能使用“while”来验证它是否被取消,因为它在这个进程中没有循环

例:

也就是说,我需要停止这个过程,即使“ExecMethod”已经运行了,也需要几分钟的时间,所以我必须停止它,不必等待他完成,这样其他人就不会继续了

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

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

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

无论如何,您都需要(应该已经)处理线程中的
InterruptedExceptions
,但是您可能需要在子进程中进行常规的“检查”,以查找中断状态(可以使用
Thread.isInterrupted()


如果您使用一个新的线程,而不是一个原始线程,那么您将得到许多额外的方法/杠杆来控制您的线程,其中一个是
shutdownlall()
,它使用
Thread.interrupt()
终止您的线程,并允许您通过
isTerminated()检查线程状态

您的用户界面不必等待工作线程完成,所以不要太担心这一点


遗憾的是,Thread.destroy()和Thread.stop()由于实现不好而被弃用。我认为没有一个好的“sigkill”类型的Java线程替代品。如果中止标志很重要的话,您将不得不对工作者重新编码以检查某种中止标志。否则,就让它浪费一点CPU。(“你不能取消保存,我已经完成了!”

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

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

private volatile boolean shouldStop;

public void cancel() {
    shouldStop = true;
}

@Override
public void run() {
    while (!shouldStop) {
        // do work
    }
}
但是线程已经带有一个标志:中断标志。虽然它不一定用于取消线程,但通常用于取消线程。事实上,标准的
ExecutorService
实现将试图通过中断线程来取消线程

除此之外,当线程被中断时,一些阻塞方法(将线程置于
BLOCKED
WAITING
状态的方法)将抛出
InterruptedException
,此时它们再次变为
RUNNABLE
。这是以前使用布尔标志的方法无法实现的

因此,使用中断来允许取消任务是一种更好的方法。您也不再需要cancel()方法:

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

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

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();
        }

    }
}
但更优雅的方法是通过
未来
对象跟踪任务(而不是它运行的特定线程)。您可以通过将
Runnable
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.
如果您有多个任务(甚至只有一个),则值得使用ExecutorService:

ExecutorService pool = Executors.newCachedThreadPool();

Future<?> submit = pool.submit(new InterruptibleTask());

pool.shutdownNow(); // depending on ExecutorService implementation this will cancel all tasks for you, the ones Executors returns do.
ExecutorService-pool=Executors.newCachedThreadPool();
Future submit=pool.submit(new interruptabletask());
pool.shutdownNow();//根据ExecutorService实现,这将取消执行者返回的所有任务。

2件事:按照您现在的方式,方法
call()
几乎会立即返回,它不会等到
execProcess()
完成。此外,停止线程的最佳方法是使用标志,并在每一步后检查它。线程应该是要退出的线程,外部请求不应该终止线程。搜索
[java]线程中断
并没有告诉您想要知道什么?中断只是一些java方法受影响的标志,但不是很多。如果您需要可靠性,那么您需要自己检查状态。您被中断的线程仍然需要检查自身,以查看它是否已被中断(通过抛出InterruptedException的方法之一,或者通过检查thread.isInterrupted()。此操作有效,但仅在下一个进程中有效,如果它已在运行,则不会停止该进程。仅在下一个进程中有效。
Thread thread = new Thread(new InterruptibleTask());
thread.start();

// some time after :

thread.interrupt();
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.
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
}
ExecutorService pool = Executors.newCachedThreadPool();

Future<?> submit = pool.submit(new InterruptibleTask());

pool.shutdownNow(); // depending on ExecutorService implementation this will cancel all tasks for you, the ones Executors returns do.