2012-03-20 30 views
0

我在桌子上敲着我的头在这里的朋友。这是我想要完成的。我有一个Main类,它将创建一个新的线程。现在,线程完成工作后,它将执行一些小的清理操作,线程停止。但是,我在UI上有一个“停止”按钮,当按下时,应该“做一些清理,然后杀死线程。问题是,我似乎无法更新我创建的新线程中的任何内容。Java - 无法停止从主类runnable

下面是一些片段:

主类

runner = new Thread(new Controller1(options)); 
runner.start(); 

在上面的代码,我打电话给我的控制器1类,并在构造函数中设置一些“选项”这是工作好到目前为止......

现在,在Controller1类中,这是wha我有...

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

问题是,从主类,我不能调用或设置“停止”为true。我可以调用runner.interrupt(),但问题是,由于线程死了,我的killAll()函数永远不会运行,并且我剩下WebDriver和Proxy仍在运行。

+0

While循环的好处,我想我把它放在那里,因为我试图找到一种方法来阻止我的主要线程。现在我已经删除了它,是的,它运行一次,但无论如何有一个覆盖,将它从run()方法和killAll()? – Whnunlife 2012-03-20 15:53:28

+0

该循环中的任何阻塞调用? – Tudor 2012-03-20 16:55:02

+0

@Whnunlife如果你发现任何有用的答案,你应该upvote或接受它,即。格雷的回答。 – 2012-03-20 17:21:54

回答

1

我会在您的主线程中调用thread.interupt()并在Runnable的循环周围使用try/finally block以确保调用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国旗,但要设置,要立即真的在循环的结束,所以我明白为什么你有一个循环的。

假设线程没有运行并立即调用killAll(),那么它挂在其中一个方法的某处。当您从主线程调用interrupt()时,无论等待什么都会抛出InterruptedException。但是,由于我没有看到任何进展,也许这些方法将它重新投掷为RuntimeException?他们至少应该做一些像下面但这仍然块的特例:

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

无论在try /最后是去确保killAll叫做正道。

+0

'catch(InterruptedException e){ //恢复中断条件 Thread.currentThread()。interrupt(); }'如果它在某种'while(true)'loop – artbristol 2012-03-20 16:01:41

+0

True @artbristol中,这可能仍然会带来异常。我调整了我的答案。谢谢。 – Gray 2012-03-20 16:04:39

+0

问题,这个try/catch,应该在runnable的run()方法中正确吗? – Whnunlife 2012-03-20 16:17:23

0

首先,您应该捕获InterruptedException,以便您的killAll()方法得到运行。 只需使用一个试试/终于

其次,为什么你不能从你的主要方法设置停止=真?

+0

我试过了,所以我做了测试,在run()里面,在while语句结尾处删除停止的= true。所以如果我运行它,它只是一个循环。然后我试着从Main中设置这个值,当点击按钮时,循环永远不会退出。 – Whnunlife 2012-03-20 16:19:34

+0

如果您查看使用“中断”的代码,您会在run()方法中看到它是否中断== true并引发InterruptedException。就像你的停止==真。 重点是:你绝不能从另一个线程强制中断运行线程。如果执行仍然应该运行,你应该在任何时候在run()中检查你的代码。如果不是 - 退出或抛出InterruptedException。全部由你自己:) 而不是停止,你可以使用Thread类中存在的isInterrupted()方法,并从主线程调用interrupt()。 – yggdraa 2012-03-20 16:48:57

+0

感谢那里的信息,所以我应该基本上有一段时间(!isInterrupted())然后,如果我调用thread.interrupt,它会得到检查为真,并得到正确的? – Whnunlife 2012-03-20 16:57:27

0

如果我明白这是正确的,你会误用while(!stopped)成语。在你的代码中,检查它是否不停止一次,然后完成所有事情,设置stopped = true并退出。你只是没有机会在开始后停止执行。当它开始时,停止的字段将不会再次被调用,直到它结束。

+0

你说得对,现在就谈! – Whnunlife 2012-03-20 15:54:12

0

首先,丢失了while(!stopped)stopped=true部分。 你还需要在线程中的每个单独阶段评估stopped(并记住运行killAll()并重新启用开始按钮当然)。

+0

我改变了我的run()方法,并将每个函数包装在if(!stopped)中,这样,如果我从main中设置stops = true,那么下一个函数将不会运行,并调用killAll。想想我的工作,看起来像业余代码,但哦。 – Whnunlife 2012-03-20 16:55:57