2012-06-09 41 views
4

某些线程在其run方法中执行一系列操作。当站关闭时,通过onStationClosed通知所有乘客。发生时,线程必须执行一些操作(例如,LeaveStation),并且线程必须终止,而不必完成所有剩余操作。在某些情况下终止线程的正确方法是什么?

什么是正确的方式做到这一点:

// 1 - By checking station's state between each operationN? 

public class Passenger extends Thread 
{ 
    Station station; 
    public void onStationClosed() 
    { 
      // Do some action before thread terminates 
    } 
    @Override 
    public void run() 
    { 
     operation1(); 
     if(station.getState == Station.Closed) return; 
     operation2(); 
     if(station.getState == Station.Closed) return; 
     operation3(); 
     if(station.getState == Station.Closed) return; 
     .. 
     operationN(); 
    } 
} 

// 2 - Throw StationClosedException from onStationClosed and catch it in Station. 

public class Passenger extends Thread 
{ 
    Station station; 
    public void onStationClosed() 
    { 
     // Do some action before thread terminates 
     throw new StationClosedException(); 
    } 
    @Override 
    public void run() 
    { 
     operation1(); 
     operation2(); 
     .. 
     operationN(); 
    } 
} 
+0

如何创建某种类型的堆栈来保存操作(这需要是一个具有operation()方法的接口),然后在while循环中迭代,但在循环开始时检查站状态? –

+2

对控制流使用异常总是不好,异常只能用于异常。我认为第一个很有趣,但仍然不理想。你能解释一下你的问题吗?你为什么需要线程?为什么你不能使用回传信号向工作人员发出信号,说明当一个电台关闭时不应再做任何工作? –

+0

我有车站和乘客。乘客去车站并尝试进入车站。乘客在车站做他们需要的东西,一旦车站关闭,即使他们没有完成他们计划做的所有事情,他们也需要离开。 – theateist

回答

2

第一个解决方案是相当不错的。但是不是很,可以考虑在一些小的操作对象包装操作和执行每次操作前检查station状态:

List<Operation> operations = Arrays.asList(new Operation1(), new Operation2(), new Operation3()); 

for(Operation operation: operations) { 
    if(!perform(operation)) { 
    return; 
    } 
} 

perform()定义如下:

private boolean perform(Operation operation) { 
    if(station.getState == Station.Closed) 
    return false; 
    operation.run(); 
    return true; 
} 

一点点牵强,但是当操作数量增加时,您会欣赏它。

我不太了解例外解决方案。如果从onStationClosed()回调中抛出该异常,它将被抛回到您的事件发件人线程,而不是Passenger线程。它不会中断你的线程。

但是,您可以使用InterruptedException来控制此流程。该解决方案与检查站状态非常相似,但是您检查标记Thread.isInterrupted()。增加的好处:I/O操作和睡眠会自动中断。你所要做的就是呼叫

Thread passenger = new Passenger(); 
passenger.interrupt(); 
Thread passenger = new Passenger(); 
passenger.interrupt(); 
+1

使用'InterruptedException'是要走的路,因为只要添加I/O,您就需要抓住这些。 – user949300

+1

只需要注意,您需要在Station上同步,因为您正在一个线程中更新它的状态并在另一个线程中使用它。 – Ravi

相关问题