3 回答

TA貢獻1946條經(jīng)驗 獲得超3個贊
您可以使用volatile boolean所有線程將不斷檢查的變量。如果一個線程將該變量的值設置為false,則所有線程都將看到新值并離開while循環(huán)。
說明:volatile變量中的讀/寫操作是原子的。除此之外,volatile 變量的值不會被緩存,所以所有線程看到的都是相同的值。
class Scratch {
private static volatile boolean isRunning = true;
public static void main(String[] args) {
Thread Task1 = new Thread(new Task1());
Task1.start();
Thread Task2 = new Thread(new Task2());
Task2.start();
// ... more threads
}
public class Task1 implements Runnable {
public void run() {
while (isRunning) {
// ...
isRunning = false; // let's stop all threads
// ...
}
}
}
public class Task2 implements Runnable {
public void run() {
while (isRunning) {
// ...
// I need to know about System.exit(0) to exit my loop
// ...
}
}
}
}

TA貢獻2051條經(jīng)驗 獲得超10個贊
自己創(chuàng)建線程被認為是“不好的做法”,您應該考慮使用 ExecutorService。同步應該通過中斷線程來完成。
class Scratch {
private final ExecutorService executorService;
public Scratch(ExecutorService es) {
this.executorService = es;
}
/** Convience constructor */
public Scratch() {this(Executors.newCachedThreadPool());}
public class Task1 implements Callable<Void> {
public Void call() throws Exception {
while(true) {
...
executorService.shutdownNow(); // interrupt all running threads
// (including Task1) started by
// given executor service
if (Thread.interrupted())
throw new InterruptedException();
}
return null;
}
}
public class Task2 implements Callable<Void> {
public Void call() throws Exception {
while(true) {
// check if the thread was interrupted, if so throw Exception
if (Thread.interrupted())
throw new InterruptedException();
}
return null;
}
}
public static void main(String ... args) {
Scratch s = new Scratch();
s.executorService.submit(new Task1());
s.executorService.submit(new Task2());
}
}

TA貢獻1865條經(jīng)驗 獲得超7個贊
除了使用volatile boolean variable實現(xiàn)的方法(這是一個很好的方法)之外,您還可以考慮使用listeners。它們通常在 Android API 中使用。
首先,創(chuàng)建定義偵聽器的接口。下面是一個例子:
public interface TaskListener {
public void onFinish();
}
現(xiàn)在,在您希望收到任務完成通知的類上實現(xiàn)此接口。往下看:
public class Task2 implements Runnable, TaskListener {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
//...
}
}
public void onFinish() {
//perform your exit operations here.
Thread.currentThread().interrupt();
}
}
現(xiàn)在,準備您的主要任務的類以接收偵聽器??匆豢矗?/p>
public class Task1 implements Runnable {
private ArrayList<TaskListener> listeners = new ArrayList<>();
public void run() {
while (true) {
// ...
this.finish();
// ...
}
}
public void addListener (TaskListener listener) {
this.listeners.add(listener);
}
private void finish() {
for(TaskListener listener: this.listeners) {
listener.onFinish();
}
}
}
完成所有設置后,現(xiàn)在可以輕松聆聽任務的完成情況。往下看:
public static void main(String[] args) {
Thread task1 = new Thread(new Task1());
Thread task2 = new Thread(new Task2());
task1.addListener(task2);
task1.start();
task2.start();
}
完畢!現(xiàn)在,每次task1.finish()調(diào)用時,它的所有偵聽器(僅task2在此示例中)都會收到通知(onFinish調(diào)用它們的方法)。
注意:TaskListener如果您不想,則沒有必要在您的所有任務中實施。這是一個使用lambda 表達式的示例:
public static void main(String[] args) {
Thread task1 = new Thread(new Task1());
Thread task2 = new Thread(new Task2());
task1.addListener(() -> {
//this entire block will be called when task1 finishes
task2.interrupt();
});
task1.start();
task2.start();
}
注2:我在手機上寫了這個答案。雖然我修改了幾次代碼,看起來還可以,但我要回家才能測試它
添加回答
舉報