来自不同函数的线程中断

我目前正在启动一个新线程并试图从另一个函数中中断它。像这样


public static void simulate(ActionEvent e){ //Runs the Simulation in a new thread, allowing for realtime updating of the Textarea

    Simulate simulation = new Simulate(0.1, Main.house);

    Thread simThread = new Thread(simulation.simulate()) {};

    simThread.start();


}


public static void pause(ActionEvent e){

    simThread.interrupt();


}

但是,暂停内的 simThread 当然是未定义的。我试图在函数之外提取模拟和 simThread 的初始化并将它们公开。但这导致尝试启动 simThread 时出现空指针异常。


任何有关如何跨函数共享线程或如何解决此问题的帮助将不胜感激。


阿波罗的战车
浏览 164回答 2
2回答

PIPIONE

提供的代码中有很多错误,我必须提前几步才能正确回答问题。1. 您使用的是哪个线程构造函数?Thread 提供了几种构造函数,它们将字符串、Runnable 或线程组作为参数。您的函数构造线程,其结果simulation.simulate()必须是上述返回类型之一才能编译。我很确定您没有意识到此时整个simulate函数正在运行并在线程启动之前完成。另请注意,您随后定义了具有空实现 (the { })的抽象 Thread 类。尝试像这样初始化线程:final Simulate simulation = new Simulate(0.1, Main.house);Thread simThread = new Thread(simulation::simulate);这会将方法simulate本身作为Runnable参数传递给 Thread 构造函数。请注意,要使其工作,模拟方法必须是 return-type void。2. 外部函数应该如何访问局部变量?在您的方法中,您声明了一个仅对方法本身可见的变量。任何外部代码应该如何解决它?您至少需要返回局部变量(因此将其公开):public static Thread simulate(ActionEvent e){  final Simulate simulation = new Simulate(0.1, Main.house);  final Thread simThread = new Thread(simulation::simulate);  simThread.start();  return simThread;}现在外部调用者将接收已创建的线程,然后可以中断它 theReturnedValue.interrupt()或者,您可以将 id 分配给您创建的线程并在内部管理它们,但这超出了本答案的范围。3. 你认为interrupt是什么?没有(合法的)方法可以阻止线程运行,因此唯一interrupt能做的就是向线程发送“请求”以停止工作。由于您还没有发布simulate方法,我只能猜测那里会发生什么。interrupt将导致所有阻塞操作突然继续并在当前线程上设置中断标志,这通常会导致InterruptedException抛出an 。您可以对此做出反应或检查Thread.interrupted方法,如果调用该函数的线程的中断标志已被某人设置(这应该是您在您的情况下创建的线程),则该方法将返回 true 。进一步阅读对于您的情况,FutureTask已被折叠并应使用。它需要一个Executor来运行实际任务。

青春有我

如果你能编译这段代码,我假设你已经在某处声明了一个simThread静态变量。显然,您可以simulate通过不重新声明来初始化该静态变量:public static void simulate(ActionEvent e){ //Runs the Simulation in a new thread, allowing for realtime updating of the Textarea    Simulate simulation = new Simulate(0.1, Main.house);    simThread = new Thread(simulation.simulate()) {};    simThread.start();}但您必须确保:simulate总是在之前被调用pause,并且simulate没有pause中间没有被调用两次。您可以像这样确保这些条件:public static synchronized void simulate(ActionEvent e){ //Runs the Simulation in a new thread, allowing for realtime updating of the Textarea    if (simThread != null) {        throw new IllegalStateException("A simulation is already running.");    }    Simulate simulation = new Simulate(0.1, Main.house);    simThread = new Thread(simulation.simulate()) {};    simThread.start();}public static synchronized void pause(ActionEvent e){    if (simThread == null) {        throw new IllegalStateException("Simulation is not running.");    }    simThread.interrupt();    simThread = null;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java