2017-06-12 70 views
0

我試圖在我的代碼中使用狀態模式。但我無法弄清楚這是否會導致與Spring的競爭狀況。這裏activestoprestart有不同的實現。將執行哪個實現取決於通過調用setCurrentInt設置了什麼currentInt。如果可以,我該如何處理這個問題。在春天,非注入場會導致競爭狀態嗎?

@Component 
public class StateService { 

    //3 states 
    @Autowired 
    @Qualifier("notActivatedState") 
    private ActiveState notActivatedState; 
    @Autowired 
    @Qualifier("stoppedState") 
    private ActiveState stoppedState; 
    @Autowired 
    @Qualifier("inUseState") 
    private ActiveState inUseState; 
    //current state 
    private Integer currentInt; 



    //Interface which was delegated to perform an act. It is not @Autowired, could there be some problem when multiple requests set currentInt to different values ? 
    private ActiveState currentState; 




    public void activate(BdCorp bdCorp) { 
    currentState.activate(bdCorp); 
    } 

    public void stop(BdCorp bdCorp) { 
    currentState.stop(bdCorp); 
    } 

    public void restart(BdCorp bdCorp) { 
    currentState.restart(bdCorp); 
    } 


    public void setCurrentInt(Integer currentInt) { 
    this.currentInt = currentInt; 
    if (currentInt == 1) { 
     this.currentState = notActivatedState; 
    } 
    if (currentInt == 2) { 
     this.currentState = inUseState; 
    } 
    if (currentInt == 3) { 
     this.currentState = stoppedState; 
    } 
    } 
} 

回答

0

當currentIn在分配currentState之間改變時,它可能會有併發問題。

而是定義例如ThreadLocal爲currentInt併爲當前狀態而不是屬性引入一個getter。

private ThreadLocal<Integer> currentIntStorage = new ThreadLocal<>(); 

private ActiveState getCurrentState() { 
    Integer currentInt = myThreadLocal.get(); 
    if (currentInt == 1) { 
     return notActivatedState; 
    } 
    else if (currentInt == 2) { 
     return inUseState; 
    } 
    else if (currentInt == 3) { 
     return stoppedState; 
    } 

    return null; 
} 

,並用它

public void activate(BdCorp bdCorp) { 
    getCurrentState().activate(bdCorp); 
} 
+0

感謝您的解決方案!我還通過使用@Scope(「prototype」)上級'StateService'類找到了一個解決方案,因此每個請求都由不同的'stateService'實例處理。這可以防止併發問題,我是對嗎?@StanislavL – fuko