所以,我为标题道歉。如果你不知道如何调用它,我很难用一句话来解释我想做什么。
因此假设我只能使用原始线程函数(wait,notify,no concurrent package)
程序有3个线程,它们都是相同的,并由主线程调用。它们表现正常,直到三个中的一个获得异常,因此它必须等待剩余的2个线程的结束才能启动恢复过程。 我在考虑一个静态变量,但我不是很确定,我希望尽可能简单。
每个帖子同时开始。
答案 0 :(得分:1)
我认为您需要java.concurrent.CountdownLatch,但是如果您无法使用java.concurrent包,则可以使用Object.wait / notify和synchronized块自行编写代码。
然后可以在每个线程的finally {}中递减锁存器,如果线程完成或发生异常,则会运行该锁存器。
然后你的主程序只需等待计数变为0。
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
答案 1 :(得分:1)
我没有看到为什么你不能像你建议的那样使用静态变量的原因。这就是我如何用内部阶级来做这件事......
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
@Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
我当然会用更合适的东西替换while (true)
。
答案 2 :(得分:0)
不确定你要做什么,但这是我能想到的那么简单(只是原生并发):
创建静态或共享volatile
布尔值
private static volatile boolean exceptionOccured=false
将上述内容设置为' true'发生异常时:
....}catch(Exception e){
exceptionOccured=true;
}
在正常的线程流中定期检查:
if (exceptionOccured)
//enter you synchronized call here
synchronized方法可能类似于:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}