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()
方法中,在处理程序上发布消息