3 回答
TA贡献1946条经验 获得超3个赞
您可以使用volatile boolean所有线程将不断检查的变量。如果一个线程将该变量的值设置为false,则所有线程都将看到新值并离开while循环。
说明: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条经验 获得超10个赞
自己创建线程被认为是“不好的做法”,您应该考虑使用 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条经验 获得超7个赞
除了使用volatile boolean variable实现的方法(这是一个很好的方法)之外,您还可以考虑使用listeners。它们通常在 Android API 中使用。
首先,创建定义侦听器的接口。下面是一个例子:
public interface TaskListener {
public void onFinish();
}
现在,在您希望收到任务完成通知的类上实现此接口。往下看:
public class Task2 implements Runnable, TaskListener {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
//...
}
}
public void onFinish() {
//perform your exit operations here.
Thread.currentThread().interrupt();
}
}
现在,准备您的主要任务的类以接收侦听器。看一看:
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();
}
}
}
完成所有设置后,现在可以轻松聆听任务的完成情况。往下看:
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();
}
完毕!现在,每次task1.finish()调用时,它的所有侦听器(仅task2在此示例中)都会收到通知(onFinish调用它们的方法)。
注意: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:我在手机上写了这个答案。虽然我修改了几次代码,看起来还可以,但我要回家才能测试它
添加回答
举报