Java 在同一线程上两次调用start方法合法吗?

Java 在同一线程上两次调用start方法合法吗?,java,android,multithreading,Java,Android,Multithreading,下面的代码导致java.lang.IllegalThreadStateException:当我在程序中第二次调用start()method时,线程已经启动了 updateUI.join(); if (!updateUI.isAlive()) updateUI.start(); 这是在调用秒时间updateUI.start()时发生的。我已经多次使用它,在点击updateUI.start()之前,线程被调用并完全运行到完成 调用updateUI.run()可以避免错误,但会导

下面的代码导致
java.lang.IllegalThreadStateException:当我在程序中第二次调用
start()
method时,线程已经启动了

updateUI.join();    

if (!updateUI.isAlive()) 
    updateUI.start();
这是在调用时间
updateUI.start()
时发生的。我已经多次使用它,在点击
updateUI.start()
之前,线程被调用并完全运行到完成

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

一个线程只能启动一次吗?如果是,那么如果我想再次运行线程,我该怎么办?此特定线程正在后台执行某些计算,如果我不在线程中执行,那么它将在UI线程中执行,并且用户等待的时间过长。

对于该方法:

开始一个线程是不合法的 不止一次。特别是 线程一旦启动,就不能重新启动 已完成执行

此外:

抛出:
-如果线程已经启动

因此,是的,
线程只能启动一次

如果是的话,如果我想做什么 再次运行线程


如果一个
线程
需要多次运行,那么应该创建一个
线程
的新实例,并在其上调用
start

正如您所说,一个线程不能多次启动

直接从马嘴里说:

开始一个线程是不合法的 不止一次。特别是 线程一旦启动,就不能重新启动 已完成执行


如果您需要重新运行线程中正在发生的任何事情,您必须创建一个新线程并运行它。

刚刚得到的答案涵盖了为什么您不应该做您正在做的事情。以下是一些解决实际问题的选项

这个特殊的线程正在做一些工作 在后台计算,如果我 不要在线程中这样做,因为它是 在UI线程中完成,并且用户已 不合理的长时间等待

转储自己的线程并使用
AsyncTask

或者在需要时创建一个新线程

或者将线程设置为在工作队列之外运行(例如,
LinkedBlockingQueue
),而不是重新启动线程。

完全正确:

开始一个线程是不合法的 不止一次。特别是 线程一旦启动,就不能重新启动 已完成执行

就重复计算而言,似乎可以使用。您已经在尝试直接调用
run()
,这意味着您已经在考虑使用
Runnable
而不是原始
线程。尝试在
Runnable
任务上使用
invokeLater
方法,看看这是否更适合您的思维模式

以下是文档中的示例:

 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工作中与invokeLater等价的是
Handler.post(Runnable)
。从其javadoc:

/**
 * 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.invokeLater
替换为
处理程序的适当post

您应该做的是创建一个Runnable,并在每次运行Runnable时用一个新线程将其包装。 这样做真的很难看,但是你可以用另一个线程包装一个线程来再次运行它的代码,但只有这样做,你才能真正做到

这样做真的很难看,但是你可以用另一个线程包装一个线程来再次运行它的代码,但只有这样做,你才能真正做到


我不得不修复一个资源泄漏,该泄漏是由一个程序员创建了一个线程引起的,但他没有开始()调用它,而是直接调用run()-方法。所以,除非你真的知道它会引起什么副作用,否则就要避免它。

重复使用线程在Java API中是非法的。
但是,您可以将其包装到可运行的实现中,然后再次运行该实例。

,我们无法再次启动线程,这样做将抛出runtimeException java.lang.IllegalThreadStateException。 >

原因是一旦run()方法被线程执行,它就会进入死状态

public class MyClass implements Runnable{

    @Override
    public void run() {
           System.out.println("in run() method, method completed.");
    }

    public static void main(String[] args) {
                  MyClass obj=new MyClass();            
        Thread thread1=new Thread(obj,"Thread-1");
        thread1.start();
        thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
    }

}
让我们举个例子- 考虑再次启动线程并对其调用start()方法(内部将调用run()方法)对我们来说就像让死人醒来并运行一样。当人的生命结束后,他会进入死亡状态

public class MyClass implements Runnable{

    @Override
    public void run() {
           System.out.println("in run() method, method completed.");
    }

    public static void main(String[] args) {
                  MyClass obj=new MyClass();            
        Thread thread1=new Thread(obj,"Thread-1");
        thread1.start();
        thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
    }

}
/*run()方法中的输出,方法已完成。线程中的异常 “main”java.lang.IllegalThreadStateException 位于java.lang.Thread.start(未知源) */


是的,我们无法开始运行线程。 如果线程已经启动,它将在运行时抛出IllegalThreadStateException

如果您真的需要启动线程,该怎么办: 选项1)如果一个线程需要运行多次,那么应该创建一个新的线程实例并调用start

一个线程只能启动一次吗

对。你可以只启动一次

如果是这样的话,那么如果我想再次运行线程,我该怎么办?这个特定的线程正在后台进行一些计算,如果我不在线程中执行,那么它将在UI线程中执行,并且用户有一个不合理的长时间等待

不要再次运行
线程。而是创建并发布在的上。您可以提交多个
Runnable
对象。如果要将数据发送回UI线程,请在
Runnable
run()
方法中,在
处理程序上发布
消息