来自其他函数的线程中断

时间:2018-10-26 08:54:02

标签: java multithreading

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

    <div itemprop="video" itemscope itemtype="http://schema.org/VideoObject" class="seovid">
     <object>
       <video width="640" controls controlsList="nodownload">
          <source src="https://www.xzy/bla.mp4">
    			Dein Browser unterstützt keine HTML5 Videos oder Du nutzt eine veraltete Version.
       </video>
       </object>
       <h3 itemprop="name“>bla</h3>
       <p itemprop="description“>bla</p>
    </div>

但是,暂停中的simThread当然是未定义的。我尝试在函数外部提取模拟和simThread的初始化,并将其公开。但这会在尝试启动simThread时导致空指针异常。

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

2 个答案:

答案 0 :(得分:0)

如果您可以编译此代码,则假定您已在某个地方声明了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();

}

但是您必须确保:

  1. simulate总是在pause之前调用,并且
  2. 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;
}

答案 1 :(得分:0)

所提供的代码中有很多错误,因此我必须提前开始一些步骤才能正确回答问题。

1。您正在使用哪个线程构造函数?

Thread提供了几个使用Strings,Runnables或Threadgroups作为参数的构造函数。您的函数使用simulation.simulate()的结果构造线程,该结果必须是上述返回类型之一才能进行编译。我很确定您还没有意识到,在线程启动之前,整个simulate函数都已运行并完成。还要注意,然后您用一个空的实现({ })定义了抽象的Thread类。

尝试像这样初始化线程:

final Simulate simulation = new Simulate(0.1, Main.house);
Thread simThread = new Thread(simulation::simulate);

这会将方法simulate本身作为Runnable参数传递给Thread构造函数。请注意,要使此方法起作用,simulate方法必须为返回类型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。您可以对此作出反应,也可以检查Thread.interrupted方法,如果某人设置了调用该函数的线程的中断标志(应该是您创建的线程),该方法将返回true。就您而言)。

进一步阅读

对于您的情况,FutureTask已折痕,应使用。它需要Executor才能运行实际任务。