Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何正确使用VAVR集合以实现线程安全?_Java_Thread Safety_Vavr - Fatal编程技术网

Java 如何正确使用VAVR集合以实现线程安全?

Java 如何正确使用VAVR集合以实现线程安全?,java,thread-safety,vavr,Java,Thread Safety,Vavr,VAVR集合是“不可变的” 所以,如果我有一个静态变量,例如,保存所有的WebSocket会话,我将如何使用VAVR使集合是线程安全的 例如: @ServerEndpoint("/actions") public class DeviceWebSocketServer { private static Set<Session> sessions = //???; // how should I initialize this? @OnOpen public

VAVR集合是“不可变的”

所以,如果我有一个静态变量,例如,保存所有的WebSocket会话,我将如何使用VAVR使集合是线程安全的

例如:

@ServerEndpoint("/actions")
public class DeviceWebSocketServer {

    private static Set<Session> sessions = //???; // how should I initialize this?

    @OnOpen
    public void open(Session session) {
        sessions = sessions.add(session); // is this OK???
    }

    @OnClose
    public void close(Session session) {
        sessions = sessions.remove(session); // is this OK??
    }
}    
@ServerEndpoint(“/actions”)
公共类设备WebSocketServer{
私有静态集会话=//???;//我应该如何初始化它?
@奥诺彭
公开作废开放(会议){
sessions=sessions.add(session);//可以吗???
}
@一次
公开作废关闭(会话){
会话=会话。删除(会话);//这样可以吗??
}
}    

您可以将不可变vavr集合包装在原子可更新的容器中,并使用其更新方法之一以原子方式更新对不可变集合的引用

@ServerEndpoint("/actions")
public class DeviceWebSocketServer {

    private static AtomicReference<Set<Session>> sessionsRef = 
            new AtomicReference<>(HashSet.empty());

    @OnOpen
    public void open(Session session) {
        sessionsRef.updateAndGet(sessions -> sessions.add(session));
    }

    @OnClose
    public void close(Session session) {
        sessionsRef.updateAndGet(sessions -> sessions.remove(session));
    }

}
@ServerEndpoint(“/actions”)
公共类设备WebSocketServer{
私有静态原子引用sessionsRef=
新的原子引用(HashSet.empty());
@奥诺彭
公开作废开放(会议){
sessionsRef.updateAndGet(会话->会话.add(会话));
}
@一次
公开作废关闭(会话){
sessionsRef.updateAndGet(会话->会话.remove(会话));
}
}

确保您在其他场景中使用JavaDoc,因为在更新函数中有一些需要被尊重以获得正确行为的要求。

对于这个用例,您也可以考虑使用并发映射:

@ServerEndpoint("/actions")
public class DeviceWebSocketServer {

    private static ConcurrentMap<String, Session> sessions = new ConcurrentHashMap<>();

    @OnOpen
    public void open(Session session) {
        sessions = sessions.putIfAbsent(session.getId(), session);
    }

    @OnClose
    public void close(Session session) {
        sessions = sessions.remove(session.getId());
    }

}
@ServerEndpoint(“/actions”)
公共类设备WebSocketServer{
私有静态ConcurrentMap会话=新建ConcurrentHashMap();
@奥诺彭
公开作废开放(会议){
sessions=sessions.putIfAbsent(session.getId(),session);
}
@一次
公开作废关闭(会话){
sessions=sessions.remove(session.getId());
}
}

in close应该被删除吗?请记住,ConcurrentHashMap只同步了save方法。读取方法不会被阻止,因此可以从映射中获取脏值。