当前位置: 首页 > 知识库问答 >
问题:

给定两个Java线程,当其中一个线程结束时,停止其中一个线程

韦俊英
2023-03-14

我正在为这个问题寻找一个干净的设计/解决方案:我有两个线程,可以运行用户想要的时间,但最终会在用户发出停止命令时停止。然而,如果其中一个线程突然终止(例如,由于运行时异常),我想停止另一个线程。

现在,这两个线程都执行一个Runnable(因此,当我说“stop a thread”时,我的意思是对Runnable实例调用一个stop()方法),我想的是避免使用线程(thread类),并使用CompletionServiceinterface,然后将这两个Runnables提交给这个服务的实例。

有了这个,我将使用完成服务的方法take(),当此方法返回时,我将停止两个Runnables,因为我知道其中至少有一个已经完成。现在,这是有效的,但如果可能的话,我想知道一个更简单/更好的解决方案。

此外,当我们有n线程并且其中一个线程一旦完成就停止执行所有其他线程时,什么是好的解决方案?

提前致谢。

共有3个答案

伍皓
2023-03-14

您可以让他们相互访问,或者回调可以访问两者的东西,这样它就可以中断对方。考虑:

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);
}
訾雅畅
2023-03-14

以下内容将帮助您了解如何将其应用于您的问题。希望它能有所帮助…

    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();
                    }
                }
            }
        }
    }

无论使用停止标志还是中断,都需要定期检查线程是否已发出停止信号。

孙德宇
2023-03-14

没有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个素数后,继续斐波那契数计算。 我的代码: 我本以为当斐波那契线停止时,其余的素数会被打印出来,但那没有发生,这背后的原因可能是什么?

    • 有两个线程,一个是打印偶数,另一个是打印奇数。在下面自定义锁的帮助下,我想按顺序打印数字。问题出在打印一些数字后(显示的数字顺序正确。)线程越来越死机。我花了一个多小时还是找不到问题,对我来说一切都很好。