在同一线程上两次调用 start 方法是否合法?

2022-08-31 11:08:30

下面的代码导致我在程序中第二次调用方法。java.lang.IllegalThreadStateException: Thread already startedstart()

updateUI.join();    

if (!updateUI.isAlive()) 
    updateUI.start();

这种情况在第次调用时发生。我已经多次单步执行它,线程被调用并完全运行到完成,然后单击。updateUI.start()updateUI.start()

调用可以避免错误,但会导致线程在UI线程(调用线程,如SO上其他文章中提到的)中运行,这不是我想要的。updateUI.run()

一个线程只能启动一次吗?如果是这样,如果我想再次运行线程,该怎么办?这个特定的线程在后台做一些计算,如果我不在线程中做,而不是在UI线程中完成,并且用户有一个不合理的长时间等待。


答案 1

Thread.start 方法的 Java API 规范中:

多次启动一个线程是违法的。特别是,线程在完成执行后可能不会重新启动。

此外:

Throws:
IllegalThreadStateException - 如果线程已经启动。

所以,是的,a只能启动一次。Thread

如果是这样,如果我想再次运行线程,该怎么办?

如果需要多次运行 a,则应该创建 一个新的实例并调用它。ThreadThreadstart


答案 2

完全正确。从文档中

多次启动一个线程是违法的。特别是,线程在完成执行后可能不会重新启动。

就您可以为重复计算做些什么而言,似乎您可以使用SwingUtilities invokeLater方法。您已经在尝试直接呼叫,这意味着您已经在考虑使用 a 而不是原始 .尝试在任务上使用这种方法,看看它是否更适合你的思维模式。run()RunnableThreadinvokeLaterRunnable

下面是文档中的示例:

 Runnable doHelloWorld = new Runnable() {
     public void run() {
         // Put your UI update computations in here.
         // BTW - remember to restrict Swing calls to the AWT Event thread.
         System.out.println("Hello World on " + Thread.currentThread());
     }
 };

 SwingUtilities.invokeLater(doHelloWorld);
 System.out.println("This might well be displayed before the other message.");

如果您将该调用替换为计算,它可能正是您所需要的。println

编辑:跟进评论,我没有注意到原始帖子中的Android标签。在 Android 工作中调用Later的等效方法是 。从它的javadoc:Handler.post(Runnable)

/**
 * Causes the Runnable r to be added to the message queue.
 * The runnable will be run on the thread to which this handler is
 * attached.
 *
 * @param r The Runnable that will be executed.
 *
 * @return Returns true if the Runnable was successfully placed in to the
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.
 */

因此,在Android世界中,您可以使用与上面相同的示例,将 替换为适当的帖子。Swingutilities.invokeLaterHandler


推荐