我正在尝试为分布式系统项目实施Raft共识算法,特别是现在我专注于领导者选举算法。基本上,有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;
}
}
正如您所看到的,在我的实现中,当您从状态切换到另一个状态时,首先您(尝试)相对于实际状态“杀死”任务,然后相对于新状态提交任务。
我将发布在追随者和候选人状态中执行的任务的“愚蠢”实施:
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}}没有捕捉到自身引发的中断?
答案 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);}
}
}