简体   繁体   中英

InterruptedException not catch?

I'm trying to implement the Raft Consensus Algorithm for a Distributed System Project, in particular now I'm concentrating about Leader Election Algorithm. Essentially, there are 3 states:

  1. Follower
  2. Candidate
  3. Leader

The state passage is pretty complicate if you don't know the algorithm, and I think that the only useful things to know is that each state perform a different task. So I implemented this classes:

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

As you can see, in my implementation when you switch from a state to another one, first you (try to) "kill" the task relative to the actual state, and then you submit the task relative to the new state.

I will post a "stupid" implementation of the task performed in the Follower and Candidate states:

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

Now, as you can imagine while I execute Follower.run() the variable future is referring to the task Follower.run() . So why if I call SwitchCandidate during Follower.run() the InterruptException thrown by future.cancel(true) is not catch by Follower.run() ?

In other words, why Follower.run() doesn't catch the interruption thrown by itself?

Interrupting a Thread

If any thread is in sleeping or waiting state (ie sleep() or wait() is invoked), calling the interrupt() method on the thread, breaks out the sleeping or waiting state throwing InterruptedException. If the thread is not in the sleeping or waiting state, calling the interrupt() method performs normal behaviour and doesn't interrupt the thread but sets the interrupt flag to true.

Example of doing So :

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

}  
}  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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