Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-无法从主类停止runnable_Java_Multithreading_Runnable - Fatal编程技术网

Java-无法从主类停止runnable

Java-无法从主类停止runnable,java,multithreading,runnable,Java,Multithreading,Runnable,我的头撞在桌子上,朋友们。这就是我想要实现的。我有一个主类,它将创建一个新线程。现在,当线程完成工作时,它将执行一些小的清理,线程将停止。然而,我在UI上有一个“停止”按钮,当按下该按钮时,应该“进行一些清理,然后杀死线程。问题是,我似乎无法更新我创建的新线程中的任何内容 以下是一些片段: 主类 runner = new Thread(new Controller1(options)); runner.start(); 在上面的代码中,我调用了我的Controller1类,并在构造函数中设置了

我的头撞在桌子上,朋友们。这就是我想要实现的。我有一个主类,它将创建一个新线程。现在,当线程完成工作时,它将执行一些小的清理,线程将停止。然而,我在UI上有一个“停止”按钮,当按下该按钮时,应该“进行一些清理,然后杀死线程。问题是,我似乎无法更新我创建的新线程中的任何内容

以下是一些片段:

主类

runner = new Thread(new Controller1(options));
runner.start();
在上面的代码中,我调用了我的Controller1类,并在构造函数中设置了一些“选项”。到目前为止,这一切都很正常

现在,在Controller1类中,这是我所拥有的

public volatile static boolean stopped;

public void run() {
    while(!stopped ){
        System.out.println("In run");
        startProxy(proxyPort);
        startWebDriver();
        driver.get(http);
        UIMainJSwing1.updateStartButton();
        stopped=true;
    }

    //Run killAll to stop webdriver and the proxy
    killAll();
    System.out.println("Thread complete");
}

问题是,在主类中,我无法调用或将“stopped”设置为true。我可以调用runner.interrupt(),但问题是,由于线程刚刚死亡,我的killAll()函数从未运行过,而我的WebDriver和代理仍在运行。

首先,您可能应该捕获InterruptedException,以便您的killAll()方法运行。 只要试一下就行了


第二,为什么不能从main方法中设置stopped=true?

如果我理解正确,您会误用while(!stopped)习惯用法。在你的代码中,你检查它是否停止过一次,然后把所有的事情都做到底,设置stopped=true并退出。你只是不给它一个机会在它开始执行后停止执行。当它开始执行时,停止的字段将永远不会再被处理,直到它结束。

我会调用
线程。interupt()
在主线程中,并在
Runnable
中使用一个循环,以确保调用
killAll()
方法

public void run() {
    try {
        while (!stopped) {
            ...
        }
    } finally {
        //Run killAll to stop webdriver and the proxy
        killAll();
        System.out.println("Thread complete");
    }
}
将始终调用finally块,即使线程被中断或抛出异常

其他几点意见:

您提到了
volatile boolean stopped
标志,但您在循环结束时立即将其设置为true,所以我确实明白了为什么您有一个循环

假设线程没有运行并立即调用
killAll()
,那么它挂起在其中一个方法中的某个位置从主线程,正在等待的任何东西都将抛出一个
中断异常
。但是由于我没有看到任何捕获正在进行,可能这些方法正在将其作为
运行时异常重新抛出
?它们至少应该执行如下操作,但这仍然会阻止异常:

 try {
     something.wait();
 } catch (InterruptedException e) {
     // restore the interrupted condition
     Thread.currentThread().interrupt();
 }

无论如何,try/finally是确保调用
killAll
的正确方法。

首先,在(!stopped)和
stopped=true时丢失
public void run() {
    try {
        while (!stopped) {
            ...
        }
    } finally {
        //Run killAll to stop webdriver and the proxy
        killAll();
        System.out.println("Thread complete");
    }
}

此外,您还需要在线程中的每个单独阶段计算
stopped
(记住运行killAll()并重新启用start按钮).

While循环的优点是,我想我把它放进去了,因为我试图找到一种方法从我的Main中停止这个线程。现在我已经删除了它,是的,它运行了一次,但是是否有一个覆盖将它从run()方法和killAll()中删除?该循环中是否有阻塞调用?@Whnunlife如果您发现任何有帮助的答案,您应该向上投票或接受它,即格雷的答案。
catch(InterruptedException e){//还原中断条件Thread.currentThread().interrupt();}
如果它是某种
while(true),那么它仍然可能正在吞噬异常
loopTrue@artbristol。我已经调整了我的答案。谢谢。问题,这个尝试/捕获,应该在运行中()我的runnable方法正确吗?对。围绕停止的循环。基本上,无论你从
开始尝试
,最后
应该有
killAll
。但是回到我的主类,我如何继续更新创建的新线程,并将其设置为“stopped=false”“那么线程将停止?我已经尝试过了,所以我所做的测试是在run()中,删除while语句末尾的stopped=true。所以如果我运行它,它只是一个循环。然后我尝试在单击按钮时从Main设置该值,但循环永远不会退出。如果查看使用“interrupted”的代码,您将看到在run()方法中,它检查interrupted==true并抛出InterruptedException。与您的stopped==true类似。关键是:您决不能强行从另一个线程中断正在运行的线程。如果执行仍然应该运行,您应该在任何时候在run()中签入代码。如果没有-退出或抛出InterruptedException。你可以使用Thread类中存在的isInterrupted()方法,并从主线程调用interrupt()。感谢那里的信息,所以我应该有一段时间(!isInterrupted())然后,如果我调用Thread.interrupt,它将被检查为true并被捕获。我更改了运行()方法,并将每个函数包装在if(!stopped)中,这样,如果我从main中设置stopped=true,则下一个函数将不会运行并调用killAll。我想我让它工作了,看起来像是业余代码,但哦,好吧。