我在尝试停止运行多个线程的程序时遇到了问题,所有运行的线程都试图找到相同的解决方案,但一旦一个线程找到了解决方案,所有其他线程都将停止。
在main方法中,我创建了一个线程组,使用for循环向其中添加线程并启动它们
ThreadGroup tg = new ThreadGroup("thread group");
Thread th;
for(int i = 0; i<4; i++){
th = new Thread(tg, new Runnable(), "Thread " + i)
th.start();
}
在实现Runnable的类中,我很难找出如何使其实现,以便一旦其中一个线程找到解决方案,所有线程都将停止。最终发生的情况是,要么其他线程继续运行,有时这些线程会相互中断并相互覆盖。
ThreadGroup tg = new ThreadGroup("thread group");
CountDownLatch latch = new CountDownLatch(1);
AtomicInteger result = new AtomicInteger();
Random random = new Random();
for (int i = 0; i < 4; i++) {
Thread th = new Thread(tg, () -> {
try {
Thread.sleep(random.nextInt(10000));
result.set(42);
latch.countDown();
System.out.println(Thread.currentThread().getName() + " completed task first");
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted before it could finish the task");
}
}, "Thread " + i);
th.start();
}
while (latch.getCount() > 0) {
try {
latch.await();
} catch (InterruptedException ignored) {
}
}
tg.interrupt();
System.out.println("The result is " + result.get());
此示例显示如何等待线程完成。
您需要确保您的操作是可中断的。Thread.sleep
如本例所示,默认情况下是可中断的。有关更多信息,请参阅oracle文档。
还要注意,不可能保证所有其他线程在完成之前都会被中断。如果您需要确保只处理一个结果,请同步对结果变量的访问,并放弃第一个结果之后的任何更改。
当意识到已经找到解决方案时,获胜的线程应该向父线程发出信号——然后父线程向所有其他子线程发出停止信号,或者直接杀死它们。
您必须中断这些线程(并处理可运行的中断)。我也不确定您是否应该使用ThreadGroup
-我记得看到过有关它们的Sonar警告。
您可能最好使用ExecutorService
并使用
ExecutorService es = Executors.newFixedThreadPool(100);
CountDownLatch cdl = new CountDownLatch(1);
for (int i = 0; i < 100; ++i) {
es.submit(() -> {
Thread.sleep(TimeUnit.SECONDS.toMillis(30)); // + exception handling
cdl.countDown();
});
}
cdl.await(); // or await(5, TimeUnit.MINUTES);
es.shutdownNow();
诀窍是:
ExecutorService
,其中包含100个线程池。CoundDownLatch
-一个屏障-计数为1。cdl.countDown();
将计数器从1减少到0。CountDownLatch
减少到0-您可能应该使用第二个版本(例如阻塞到5分钟)。如果所有的< code>Runnable都失败,则不会有结果:要么使用最大等待时间,要么添加另一个< code>CountDownLatch,这次计数为100(线程数),在< code>try/finally中使用< code>countDown(),在另一个线程中,中断在< code>cdl上等待的线程。你也可以在一个循环中这样做:
CountDownLatch allCdl = new CountDownLatch(100);
for (;allCdl.getCount() != 0;) {
if (!cdl.await(60, TimeUnit.SECONDS)) {
if (allCdl.getCount() == 0) {
break;
}
}
}
但是,getCount()的javadoc提到此方法通常用于调试和测试目的。(参见CyclicBarrier)。不确定这是否是正确的用法。
我正在为这个问题寻找一个干净的设计/解决方案:我有两个线程,可以运行用户想要的时间,但最终会在用户发出停止命令时停止。然而,如果其中一个线程突然终止(例如,由于运行时异常),我想停止另一个线程。 现在,这两个线程都执行一个(因此,当我说“stop a thread”时,我的意思是对实例调用一个stop()方法),我想的是避免使用线程(thread类),并使用interface,然后将这两个Runn
以下是问题陈述: 编写一个java程序,使用线程计算前25个素数,并计算前50个斐波那契数。将计算斐波那契数的线程的优先级设置为8,将另一个设置为5。在计算了30个斐波那契数之后,让这个线程进入睡眠状态,开始计算素数。计算完25个素数后,继续斐波那契数计算。 我的代码: 我本以为当斐波那契线停止时,其余的素数会被打印出来,但那没有发生,这背后的原因可能是什么?
我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以在不锁定其他两个线程的情况下继续工作? 我尝试了join(),但是它需要从线程调用,线程必须等待另一个线程,没有办法执行类似thread2.join(thread1)的操作;因此,如果我在main()中调用join,我将有效地停止主线程的执行,而不仅仅是Thread2的执行。 #编辑:为什么我
问题内容: 我在Java中的线程上有些挣扎,我有三个线程- 线程1,线程2和线程3。那些启动时正在执行某些任务,我想通过thread1停止这两个线程。我将thread1放在,然后停止两个线程,但是两个线程的进程仍在运行。你有什么想法吗? 问题答案: 您如何试图阻止他们??警告此方法已弃用。 而是考虑对线程1使用某种标志来与线程2和3通信,它们应该停止。实际上,您可能会使用interrupts。 下
我有一个带有静态ConcurrentQueue的类。一个类接收消息并将其放入队列中,而这个类上的另一个线程从该队列中读取消息并一次处理一个。使用cancellationtoken中止该方法。 清空队列的方法如下所示: 我的测试方法如下: 因此,我在自己的线程中启动我的出列方法,并使用一个新的取消令牌。然后我将一些消息排队,给进程一秒钟时间来处理它们,然后使用源代码。Cancel(false)结束线
问题内容: 因此,我的目标是让函数启动自己的线程,以便可以并行运行,而不必等待上一个线程完成。问题在于,它似乎不是多线程的(意味着一个线程在另一个线程开始之前就完成了)。 我也有该函数的内部,但似乎启动的线程的标识与从其运行python脚本的主线程相同。我认为我的方法不正确。 问题答案: 这是常见错误,容易出错。 只需在主线程中一次执行您的函数,然后将(我想为您函数的返回值)作为函数传递给线程,这