2017-06-12 77 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