繁体   English   中英

InterruptedException没有捕获?

[英]InterruptedException not catch?

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

  1. 信徒
  2. 候选人
  3. 领导

如果您不了解算法,那么状态段落非常复杂,我认为唯一有用的事情是每个州执行不同的任务。 所以我实现了这个类:

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;
    }
}

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

我将在Follower和Candidate状态中发布任务的“愚蠢”实现:

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()没有捕获自身抛出的中断?

中断线程

如果任何线程处于休眠或等待状态(即调用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);}  

}  
}  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM