public void stop(){
setRun(false);
inComingWorkThread.interrupt();
outGoingWorkThread.interrupt();
}
我试图使用中断调用来阻止这些线程。我得到了一个中断异常。
public class OutgoingListWorker implements Runnable{
@Override
public void run() {
while(mRunning){
WorkOrder workOrder = getWorkOrder();
//do something
}
}
public synchronized WorkOrder getWorkOrder(){
while(mWorkOrderList.size() == 0){
try {
this.wait();
} catch (InterruptedException e) {e.printStackTrace();}
}
return mWorkOrderList.poll();
}
public synchronized void addWorkOrder(WorkOrder workOrder){
this.notify();
mWorkOrderList.add(workOrder);
}
问题是getWokrOrder调用等待,如果这次中断发生,那么它不会杀死线程..如何安全地杀死被阻塞的线程?提前谢谢..
答案 0 :(得分:2)
我认为这是因为你抓住了InterruptedException
并继续循环......
有两种方法可以解决这个问题:
抓住循环外的InterruptedException
并返回null
。
public synchronized WorkOrder getWorkOrder() {
WorkOrder workOrder = null;
try {
while(mWorkOrderList.size() == 0) {
this.wait();
}
mworkOrder = WorkOrderList.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
return workOrder;
}
使用此选项,您需要处理getWorkOrder()
方法中null
返回run()
的情况:
if (workOrder != null) {
//do something
}
或者其次,你可以抛出InterruptedException
并强制你的run()
方法对此做些什么。
public synchronized WorkOrder getWorkOrder() throws InterruptedException {
while(mWorkOrderList.size() == 0){
this.wait();
}
return WorkOrderList.poll();
}
作为旁注,不需要维护mRunning
变量。这正是中断为你做的事情!
而不是:
while(mRunning) {
WorkOrder workOrder = getWorkOrder();
//do something
}
只需写下:
while(!Thread.interrupted()) {
WorkOrder workOrder = getWorkOrder();
//do something
}
然后你根本不需要拨打setRun(false);
!这是一个关于中断的好教程:http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
答案 1 :(得分:1)
您可以随时将mRunning
作为条件添加到wait()
中的getWorkOrder()
循环中:
while(mWorkOrderList.size() == 0 && mRunning){
try {
this.wait();
} catch (InterruptedException e) {e.printStackTrace();}
}
if (mWorkOrderList.size() > 0) {
return mWorkOrderList.poll();
}
return null;
现在,当你中断线程时,循环条件不会成立,你将退出wait()
循环。您还需要确保实际存在要返回的订单(如上所示),并且您还必须在run()
循环中添加空检查(未显示)。