我正在为这个问题寻找一个干净的设计/解决方案:我有两个线程,可以运行用户想要的时间,但最终会在用户发出停止命令时停止。然而,如果其中一个线程突然终止(例如,由于运行时异常),我想停止另一个线程。
现在,这两个线程都执行一个Runnable
(因此,当我说“stop a thread”时,我的意思是对Runnable
实例调用一个stop()方法),我想的是避免使用线程(thread类),并使用CompletionService
interface,然后将这两个Runnables提交给这个服务的实例。
有了这个,我将使用完成服务的方法take()
,当此方法返回时,我将停止两个Runnables,因为我知道其中至少有一个已经完成。现在,这是有效的,但如果可能的话,我想知道一个更简单/更好的解决方案。
此外,当我们有n
线程并且其中一个线程一旦完成就停止执行所有其他线程时,什么是好的解决方案?
提前致谢。
您可以让他们相互访问,或者回调可以访问两者的东西,这样它就可以中断对方。考虑:
MyRunner aRunner = new MyRunner(this);
MyRunner bRunner = new MyRunner(this);
Thread a = new Thread(aRunner);
Thread b = new Thread(brunner);
// catch appropriate exceptions, error handling... probably should verify
// 'winner' actually is a or b
public void stopOtherThread(MyRunner winner) {
if(winner == aRunner ) bRunner .stop(); // assumes you have stop on class MyRunner
else aRunner.stop();
}
// later
a.start();
b.start();
// in your run method
public void run() {
// la de da de da
// awesome code
while(true) fork();
// other code here
myRunnerMaster.stopOtherThread(this);
}
以下内容将帮助您了解如何将其应用于您的问题。希望它能有所帮助…
import java.util.*;
public class x {
public static void main(String[] args) {
ThreadManager<Thread> t = new ThreadManager<Thread>();
Thread a = new MyThread(t);
Thread b = new MyThread(t);
Thread c = new MyThread(t);
t.add(a);
t.add(b);
t.add(c);
a.start();
b.start();
c.start();
}
}
class ThreadManager<T> extends ArrayList<T> {
public void stopThreads() {
for (T t : this) {
Thread thread = (Thread) t;
if (thread.isAlive()) {
try { thread.interrupt(); }
catch (Exception e) {/*ignore on purpose*/}
}
}
}
}
class MyThread extends Thread {
static boolean signalled = false;
private ThreadManager m;
public MyThread(ThreadManager tm) {
m = tm;
}
public void run() {
try {
// periodically check ...
if (this.interrupted()) throw new InterruptedException();
// do stuff
} catch (Exception e) {
synchronized(getClass()) {
if (!signalled) {
signalled = true;
m.stopThreads();
}
}
}
}
}
无论使用停止标志还是中断,都需要定期检查线程是否已发出停止信号。
没有Runnable。stop()
方法,因此这是一个明显的非启动程序。
不要使用线程停止 ()
!在绝大多数情况下,它从根本上是不安全的。
如果正确实现,以下是几种应该有效的方法。
> < li>
您可以让两个线程定期检查某个公共标志变量(例如,将其称为< code>stopNow),并安排两个线程在完成时设置该变量。(标志变量需要是易变的...或者适当地同步。)
您可以让两个线程定期调用< code > thread . is interrupted()方法来查看它是否被中断。然后每个线程都需要在完成时调用另一个线程上的< code>Thread.interrupt()。
我知道Runnable没有那个方法,但是我传递给线程的Runnable的实现有,调用它的时候runner会完成run()方法(类似于Corsika的代码,在这个答案下面)。
据我所知,Corsika的代码假设有一个stop()
方法在调用时会做正确的事情。真正的问题是你是如何实现它的?或者您打算如何实现它?
>
如果您已经有一个有效的实现,那么您就有了解决问题的方法。
否则,我的答案给出了两种实现“立即停止”功能的可能方法。
我很欣赏你的建议,但我怀疑,“定期检查/调用”如何转化为代码?
这完全取决于Runnable.run()
方法执行的任务。它通常需要向某些循环添加检查/调用,以便测试合理地频繁发生…但不太频繁。您还想只检查何时停止计算是安全的,这是您必须自己解决的另一件事。
我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以在不锁定其他两个线程的情况下继续工作? 我尝试了join(),但是它需要从线程调用,线程必须等待另一个线程,没有办法执行类似thread2.join(thread1)的操作;因此,如果我在main()中调用join,我将有效地停止主线程的执行,而不仅仅是Thread2的执行。 #编辑:为什么我
问题内容: 我在Java中的线程上有些挣扎,我有三个线程- 线程1,线程2和线程3。那些启动时正在执行某些任务,我想通过thread1停止这两个线程。我将thread1放在,然后停止两个线程,但是两个线程的进程仍在运行。你有什么想法吗? 问题答案: 您如何试图阻止他们??警告此方法已弃用。 而是考虑对线程1使用某种标志来与线程2和3通信,它们应该停止。实际上,您可能会使用interrupts。 下
我在尝试停止运行多个线程的程序时遇到了问题,所有运行的线程都试图找到相同的解决方案,但一旦一个线程找到了解决方案,所有其他线程都将停止。 在main方法中,我创建了一个线程组,使用for循环向其中添加线程并启动它们 在实现Runnable的类中,我很难找出如何使其实现,以便一旦其中一个线程找到解决方案,所有线程都将停止。最终发生的情况是,要么其他线程继续运行,有时这些线程会相互中断并相互覆盖。
问题内容: 看一下这段代码: 通常,到达的结尾时,程序会终止。但是在此示例中,程序将打印“ main of End”,然后继续运行,因为线程仍在运行。有没有一种方法可以使线程在结束时 自动 停止,而无需使用类似的东西? 问题答案: 您正在创建的线程是独立的,并且不依赖于主线程终止。您可以使用线程。 当没有其他线程在运行时,守护进程线程将由JVM终止,它也包括一个执行主线程。
以下是问题陈述: 编写一个java程序,使用线程计算前25个素数,并计算前50个斐波那契数。将计算斐波那契数的线程的优先级设置为8,将另一个设置为5。在计算了30个斐波那契数之后,让这个线程进入睡眠状态,开始计算素数。计算完25个素数后,继续斐波那契数计算。 我的代码: 我本以为当斐波那契线停止时,其余的素数会被打印出来,但那没有发生,这背后的原因可能是什么?
有两个线程,一个是打印偶数,另一个是打印奇数。在下面自定义锁的帮助下,我想按顺序打印数字。问题出在打印一些数字后(显示的数字顺序正确。)线程越来越死机。我花了一个多小时还是找不到问题,对我来说一切都很好。