[英]how to stop worker threads when work is done in one of them?
我正在进行一个简单的模拟,就像破解哈希一样,现在我希望所有其他工作人员中的一个找到结果时停止吗? 除了停止,是否还有其他方法可以停止使用?
import java.util.Random;
class Worker extends Thread{
int target,start,current,end;
public Worker(int target, int start, int end) {
super();
this.target = target;
this.start = start;
this.end = end;
}
@Override
public void run() {
current=start;
while(target!=current){
System.out.println("Not found target at "+current);
current++;
if(current==end){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(target==current){
System.out.println(target+" found");
}
}
}
public class RandomBreak {
public static void main(String[] args) {
Random r=new Random(100);
int target=r.nextInt(100);
System.out.println("trying to search "+target);
Worker w1=new Worker(target,1,30);
Worker w2=new Worker(target,30,60);
Worker w3=new Worker(target,60,90);
Worker w4=new Worker(target,90,100);
w1.start();
w2.start();
w3.start();
w4.start();
}
}
当一个线程找到答案时,请在其他线程上调用Thread.interrupt()。 当您捕获InterruptedException时,退出工作线程。
如果您的“真实”代码没有thread.sleep(),那么只需偶尔检查Thread中断标志,例如:
if( Thread.interrupted() ) {
throw new InterruptedException();
}
使用公共数据结构存储标志,并将数据结构的相同实例传递给每个工作线程。 找到目标的工人将在退出前设置标志。 检查while循环中的标志以及目标。 程式码片段:
public WorkStatus {
private volatile boolean completed;
public boolean isCompleted() {
return completed;
}
public synchronized void markCompleted(boolean completed) {
this.completed = completed;
}
}
public Worker implements Runnable {
.
.
private WorkStatus workStatus;
public Worker(int target, int start, int end, WorkStatus workStatus) {
.
.
this.workStatus = workStatus;
}
@Override
public void run() {
.
while(!workStatus.isCompleted() && target!=current) {
.
}
if(target==current) {
workStatus.markCompleted(true);
.
}
}
}
确保将相同的WorkStatus实例传递给所有Worker实例。
创建一个循环以启动线程并将其添加到列表中,找到答案后,您可以遍历该列表以停止其他线程。 如果使用线程池,则可以使用ThreadPoolExecutor.shutdownNow()停止池中的所有其余线程。
停止执行线程的最可靠方法是使用中断并自行实现中断处理。 您可以使用Thread.interrupt()
更改Thread.interrupt()
的中断状态,并使用Thread.currentThread().isInterrupted()
检查线程是否被中断。
在您的情况下,代码可能如下所示:
import java.util.Random;
class Worker extends Thread {
int target, start, current, end;
public Worker(final int target, final int start, final int end) {
super();
this.target = target;
this.start = start;
this.end = end;
}
@Override
public void run() {
current = start;
while (target != current && !Thread.currentThread().isInterrupted()) {
System.out.println("Not found target at " + current);
current++;
if (current == end) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
if (target == current) {
Thread.currentThread().interrupt();
System.out.println(target + " found");
}
}
}
Worker线程将搜索给定的编号,并反复检查该线程是否被中断。 如果线程被中断,则意味着另一个线程找到了该号码。 如果线程找到了要查找的编号,则调用Thread.currentThread().interrupt()
向主方法发出已找到该编号的信号,并终止其他工作线程。
主要方法如下所示:
public static void main(final String[] args) {
Random r = new Random(100);
int target = r.nextInt(100);
System.out.println("trying to search " + target);
Worker w1 = new Worker(target, 1, 30);
Worker w2 = new Worker(target, 30, 60);
Worker w3 = new Worker(target, 60, 90);
Worker w4 = new Worker(target, 90, 100);
w1.start();
w2.start();
w3.start();
w4.start();
while (true) {
if (w1.isInterrupted() || w2.isInterrupted() || w3.isInterrupted() || w4.isInterrupted()) {
w1.interrupt();
w2.interrupt();
w3.interrupt();
w4.interrupt();
break;
} else if (!w1.isAlive() && !w2.isAlive() && !w3.isAlive() && !w4.isAlive()) {
System.out.println("Invalid search number.");
break;
}
}
}
在main方法中,我们反复检查线程之一是否被中断。 如果是,则中断其他线程并结束执行。 if子句if (!w1.isAlive() && !w2.isAlive() && !w3.isAlive() && !w4.isAlive())
的另一部分是安全检查,如果用户给出了一个线程数不要寻找。 如果所有线程均已完成执行,但未找到编号,则结束程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.