Thread.suspend()和.resume()的替代方案

yes*_*nes 7 java multithreading

我有一大段代码不是循环,只是一个发生一次但需要一些时间的命令列表.我需要它根据更改的布尔值在任何点暂停或终止它.我可以使用不同的线程来暂停,恢复和停止此代码,但这些方法已被弃用,所以我想避免使用它们.我可以检查每行代码之间的布尔值,但我希望有一个更优雅的解决方案.有没有办法做到这一点?

Ste*_*n C 5

我可以检查每行代码之间的布尔值,但我希望有一个更优雅的解决方案.有没有办法做到这一点?

很不幸的是,不行.

要替换暂停/恢复,您真正需要的是一个线程"暂停"另一个线程,而不涉及第二个线程的代码.

这在当前规范和实现的Java中是不可能安全的.

不推荐使用的Thread方法是一个线程杀死,停止/暂停,恢复另一个线程的唯一方法......如果另一个线程没有主动协作.它们被弃用了,因为(简而言之)在任何当前的主流JVM 1中都无法安全地实现这种控制.

您可以做的最好的事情是将暂停/恢复逻辑包装在第二个线程在适当的位置调用的方法中.(这可能应该使用wait/notify ...或等效的...来处理恢复.但是wait/notify 本身并不能解决你暂停/恢复非协作线程的明确要求.)


1 - 你需要像Isolates API这样的东西.已经尝试在研究项目中实现它,但AFAIK Isolates从未在生产JVM中实现.


Vit*_*ius 2

处理中断线程(在本例中为暂停或停止线程)的正确方法自然是使用Thread#interrupt(). 它的设计使您可以定义可以中断线程的安全点,这对您来说自然是每个任务之间的点。因此,为了避免在每个任务之间手动检查变量,并且能够轻松地从中断处恢复,您可以将任务存储为Runnables 列表,并记住您中断时在列表中的位置,像这样:

public class Foo {
    public static void runTask(Runnable task) throws InterruptedException {
        task.run();
        if (Thread.interrupted()) throw new InterruptedException();
    }
    Runnable[] frobnicateTasks = new Runnable[] {
        () -> { System.out.println("task1"); },
        () -> { Thread.currentThread().interrupt(); }, //Interrupt self only as example
        () -> { System.out.println("task2"); }
    };
    public int frobnicate() {
        return resumeFrobnicate(0);
    }
    public int resumeFrobnicate(int taskPos) {
        try {
            while (taskPos < frobnicateTasks.length)
                runTask(frobnicateTasks[taskPos++]);
        } catch (InterruptedException ex) {
        }
        if (taskPos == frobnicateTasks.length) {
            return -1; //done
        }
        return taskPos;
    }
    public static void main(String[] args) {
        Foo foo = new Foo();
        int progress = foo.frobnicate();
        while (progress != -1) {
            System.out.println("Paused");
            progress = foo.resumeFrobnicate(progress);
        }
        System.out.println("Done");
    }
}
-->
task1
Paused
task2
Done
Run Code Online (Sandbox Code Playgroud)