说我有类似的东西
public void run(){
Thread behaviourThread = new Thread(abstractBehaviours[i]);
behaviourThread.start();
}
我想等到abstractBehaviours [i] run方法已经完成或运行5000毫秒。我怎么做? behaviourThread.join(5000)似乎没有这样做afaik(我的代码出了问题,我已经把它归结为那个)。
所有抽象的abstractBehaviour类当然都是Runnable。我不想在每个run方法中实现它,因为它看起来很丑陋并且有许多不同的行为,我更愿意在调用/执行线程中使用它并且只执行一次。
解决方案?第一次做这样的线程。谢谢!
编辑:因此中断解决方案将是理想的(需要对AbstractBehaviour实现进行最小的更改)。但我需要线程停止,如果它已经完成或已经过了5000毫秒,所以类似下面的东西将无法工作,因为线程可能在父线程中的while循环之前完成。合理?任何解决这个问题的方法,我都很乐意从明确启动线程的线程中做到这一点。
long startTime = System.currentTimeMillis();
behaviourThread.start();
while(!System.currentTimeMilis - startTime < 5000);
behaviourThread.interrupt();
try {
behaviourThread.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
编辑:没关系我看到有一个Thread.isAlive()方法,所有解决的我认为
答案 0 :(得分:6)
执行此操作的最佳方法是使用线程中断机制。工作线程/ Runnable需要定期调用Thread.interrupted()
以查看是否该停止。等式的第二部分是一个单独的线程需要在5000毫秒过后在工作线程上调用Thread.interrupt()
。
使用线程中断(使用标志的定制解决方案)的优点包括:
interrupted()
状态始终可用于当前线程。您不需要传递对象句柄或使用单例。Thread.interrupt()
。 编辑 - 正如评论者指出的那样,您可以使用Thread.interrupted()
或Thread.currentThread().isInterrupted()
来测试当前线程是否已被中断。两种方法的主要区别在于前者清除了中断的标志,但后者没有。
答案 1 :(得分:3)
你不能从run方法外部执行此操作 - run方法必须检查某个变量以查看它是否应该退出。例如:
class InterruptableRunnable implements Runnable
{
private volatile boolean stop;
public setStop() {
stop = true;
}
public void run() {
while (!stop)
{
//do some work and occassionaly fall through to check that stop is still true
}
}
}
关键是运行循环中的代码偶尔会检查停止标志。然后,您可以连接一个计时器,在5000毫秒后将stop设置为true。
最后,最好不要直接使用Threads,使用优秀的Concurrency Framework。 Concurrency Tutorial是一个很好的起点,书籍Java Concurrency in practice非常出色。
答案 2 :(得分:1)
您可以使用java.util.concurrent包。
ExecutorService service = Executors.newCachedThreadPool();
Future future = service.submit(behaviourThread);
long startTime = System.currentTimeMillis();
while (!future.isDone()) {
if (System.currentTimeMillis() - startTime > 5000) {
future.cancel(true);
break;
}
}
// TODO: more work here
//don't forget to shutDown your ThreadPool
service.shutDown();
此代码将在5秒后停止您的线程,如果它到那时还没有完成它的工作。如果您选中 behaviourThread.isAlive() ,则会显示 false 。
答案 3 :(得分:-1)
您可以通过实施Runnable
来实现public void run()
{
long time = System.nanoTime(),
end = time + 5 000 000 000; // just better formatting
do {
...my code
} while (System.nanoTime() < end && myOwnCondition);
}
中断不是一个很好的解决方案,因为你需要从外部访问线程 它扰乱了程序流程。线程可以随时在您的代码中终止 使清理变得困难。请养成让线程运行到最后的习惯,否则会打开令人讨厌且难以处理的错误。
如果您的程序太重,以至于在任务完成之前您不知道到达终点,我建议使用标记的中断:
do {
breakout:
{
..my code
if (timetest)
break breakout;
}
// cleanup
...
} while (...);