java 在一个线程中启动另一个线程_java - 在同一个线程上调用start方法两次是合法的吗?...

java - 在同一个线程上调用start方法两次是合法的吗?

当我在程序中第二次调用updateUI.start()方法时,以下代码导致updateUI.run()。

updateUI.join();

if (!updateUI.isAlive())

updateUI.start();

这是第二次调用updateUI.run()时发生的。 我已经多次执行它并且调用线程并且在完成updateUI.start()之前完成运行完成。

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

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

10个解决方案

107 votes

从Thread方法的Java API规范:

启动一个线程永远不合法   不止一次。 特别是,a   一旦线程可能无法重新启动   已完成执行。

此外:

抛出:

Thread - 如果线程已经启动。

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

如果是这样,如果我愿意,我该怎么做   再次运行线程?

如果需要多次运行Thread,则应该创建Thread的新实例并在其上调用start。

coobird answered 2019-09-11T05:20:20Z

13 votes

非常正确。 从文档:

启动一个线程永远不合法   不止一次。 特别是,a   一旦线程可能无法重新启动   已完成执行。

就重复计算可以做什么而言,似乎可以使用SwingUtilities invokeLater方法。 您已经在尝试直接调用Swingutilities.invokeLater,这意味着您已经在考虑使用Handler而不是原始Thread。尝试在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.");

如果用计算替换Swingutilities.invokeLater调用,它可能正是您所需要的。

编辑:跟进评论,我没有注意到原帖中的Android标记。 相当于Android工作中的invokeLater是Swingutilities.invokeLater.来自它的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替换为适当的帖子Handler。

Bob Cross answered 2019-09-11T05:21:23Z

3 votes

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

这个特定的线程正在做一些   在后台计算,如果我   不要在线程中执行它而不是它   在UI线程中完成并且用户具有   一段不合理的漫长等待。

转储您自己的线程并使用LinkedBlockingQueue。

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

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

CommonsWare answered 2019-09-11T05:22:16Z

3 votes

不,我们无法再次启动Thread,这样做会抛出runtimeException java.lang.IllegalThreadStateException。>

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

我们举一个例子 - 考虑再次启动线程并在其上调用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()方法中输出OUTPUT,方法已完成。 线程中的异常   “main”java.lang.IllegalThreadStateException       在java.lang.Thread.start(未知来源)  */

检查一下

Sameer Kazi answered 2019-09-11T05:23:11Z

2 votes

你应该做的是创建一个Runnable,并在每次要运行Runnable时用新线程包装它。这样做真的很难看,但是你可以用另一个线程包装一个线程来再次运行它的代码,但这只是你必须这样做。

Peter Lawrey answered 2019-09-11T05:23:38Z

1 votes

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

直接来自马口:Java API Spec

启动一个线程永远不合法   不止一次。 特别是,a   一旦线程可能无法重新启动   已完成执行。

如果你需要重新运行你的线程中发生的任何事情,你将不得不创建一个新线程并运行它。

alanlcode answered 2019-09-11T05:24:20Z

0 votes

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

Aaron He answered 2019-09-11T05:24:48Z

0 votes

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

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

riteeka answered 2019-09-11T05:25:22Z

0 votes

线程只能启动一次吗?

是。 你可以开始一次。

如果我想再次运行该线程,我该怎么做?这个特定的线程在后台进行一些计算,如果我不在线程中执行它而不是在UI线程中完成并且用户有一个不合理的 漫长的等待。

不要再次运行Thread。 而是创建Runnable并将其发布在HandlerThread的Handler上。 您可以提交多个Runnable个对象。 如果想要将数据发送回UI线程,请使用Runnable run()方法,在Handler的UI线程上发布Message并处理handleMessage

有关示例代码,请参阅此帖子:

Android:在线程中敬酒

Ravindra babu answered 2019-09-11T05:26:24Z

-1 votes

这样做真的很难看,但是你可以用另一个线程包装一个线程来再次运行它的代码,但这只是你必须这样做。

我不得不修复由创建Thread但没有start()的程序员引起的资源泄漏,他直接调用了run()方法。 所以要避免它,除非你真的知道它会导致什么副作用。

Torben answered 2019-09-11T05:26:59Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值