InterruptedException没有捕获?

时间:2015-02-16 20:43:12

标签: java interrupt future

我正在尝试为分布式系统项目实施Raft共识算法,特别是现在我专注于领导者选举算法。基本上,有3种状态:

  1. 从动
  2. 候选
  3. 利达
  4. 如果您不了解算法,状态段落非常复杂,我认为唯一有用的事情是每个州执行不同的任务。所以我实现了这个类:

    public class ServerStateExecutor {
        private ExecutorService executor;
        private ServerState state;
        private Future<?> future;
    
        public ServerStateExecutor()
        {
            executor = Executors.newSingleThreadExecutor();
            SwitchFollower();
        }
    
        public void ExecuteState(ServerState state)
        {
            if(future!=null) {
                future.cancel(true);
            }
            System.out.println("Submitting...");
            future = executor.submit(state);
        }
    
        public void SwitchFollower() {
            ExecuteState(new Follower(this));
        }
    
        public void SwitchCandidate() {
            ExecuteState(new Candidate(this));//if true then no Timeout
        }
    
        public void SwitchLeader() {
            ExecuteState(new Leader(this));
        }
    }
    
    public abstract class ServerState implements Runnable {
        protected ServerStateExecutor executor;
    
        public abstract void run();
        public ServerState(ServerStateExecutor executor)
        {
            this.executor = executor;
        }
    }
    

    正如您所看到的,在我的实现中,当您从状态切换到另一个状态时,首先您(尝试)相对于实际状态“杀死”任务,然后相对于新状态提交任务。

    我将发布在追随者和候选人状态中执行的任务的“愚蠢”实施:

    public class Follower extends ServerState {
    
        public Follower(ServerStateExecutor executor) {
            super(executor);
        }
        @Override
        public void run() {
            try {
                Thread.currentThread().sleep(10000);
                executor.SwitchCandidate();
            }
            catch(Exception e){System.out.println("INTERRUPTION!");}
        }
    }
    
    public class Candidate extends ServerState {
    
        public Candidate(ServerStateExecutor executor) {
            super(executor);
        }
    
        @Override
        public void run() {
            try {
                Thread.currentThread().sleep(3000);
            } catch (InterruptedException e) {
                System.out.println("Interrupted!");
            }
            executor.SwitchFollower();
        }
    }
    

    现在,正如您在执行Follower.run()时所想象的那样,变量future指的是任务Follower.run()。那么,为什么我在SwitchCandidate Follower.run()期间InterruptException future.cancel(true)Follower.run()引发Follower.run()

    换句话说,为什么{{1}}没有捕捉到自身引发的中断?

1 个答案:

答案 0 :(得分:0)

中断线程

  

如果任何线程处于休眠或等待状态(即sleep()或wait()   被调用),在线程上调用interrupt()方法,爆发   抛出InterruptedException的睡眠或等待状态。如果   线程未处于休眠或等待状态,调用   interrupt()方法执行正常行为并且不会中断   线程但将中断标志设置为true。

这样做的例子:

class TestInterruptingThread1 extends Thread{  
public void run(){  
try{  
Thread.sleep(1000);  
System.out.println("task");  
}catch(InterruptedException e){  
throw new RuntimeException("Thread interrupted..."+e);  
}  

}  

public static void main(String args[]){  
TestInterruptingThread1 t1=new TestInterruptingThread1();  
t1.start();  
try{  
t1.interrupt();  
}catch(Exception e){System.out.println("Exception handled "+e);}  

}  
}