簡體   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