繁体   English   中英

如何正确使用VAVR集合是线程安全的?

[英]How to correctly use VAVR collections to be thread safe?

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

您可以将不可变的vavr集合包装在可自由更新的AtomicReference ,并使用其中一种更新方法以原子方式更新对不可变集合的引用。

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

}

如果要在其他场景中使用它们,请确保读取AtomicReference的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());
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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