java - Server EndPoint for WebSocket Java API 中的 volatile 变量?

标签 java multithreading websocket thread-safety volatile

看看网络上的其他示例,当通过 Java API for WebSocket 创建服务器端点时,所有 EndPoint 实例之间的共享变量被定义为静态的,但不是 volatile 的。我想知道原因。

据我了解,打开 websockets 的客户端将在服务器中创建一个新线程。那么为了线程安全,不应该将 EndPoint 实例之间的共享变量定义为 volatile 吗?

即而不是:

@ServerEndpoint("/endpoint")
public class WebsocketEndPoint {
   private static Set<WebsocketEndPoint> endPoint = new CopyOnWriteArraySet<WebsocketEndPoint> ();

   @OnOpen
   public void onOpen(Session session, String message) {
...

这段代码不是更好吗?:

@ServerEndpoint("/endpoint")
public class WebsocketEndPoint {
   private static volatile Set<WebsocketEndPoint> endPoint = new CopyOnWriteArraySet<WebsocketEndPoint> ();

   @OnOpen
   public void onOpen(Session session, String message) {
...

最佳答案

您需要使用volatile关键字,如果某个变量被某个线程修改,但可能被另一个线程读取(并且没有任何其他同步机制)。

所以问题是是否存在某些线程更改Set的场景到另一个线程,第二个线程尝试访问它。例如,如果某个线程执行此操作:endPoint = new HashSet<>() ,而另一个线程执行此操作:endPoint.get(...) ,那么是的,Set应该是volatile

但是如果不同的线程使用相同的Set实例,然后 endPoint引用不会改变,并且是“有效的最终”。在这种情况下,无需添加 volatile关键字。

所以简短的答案是“这取决于”,因为我们需要查看完整的示例来看看 Set 是否有效。应该是不稳定的。不过,我确实想指出一件事 - 使用 CopyOnWriteArraySet似乎有点奇怪,因为对集合的修改只会在修改线程的上下文中创建修改后的副本(这就是写时复制的含义)。

关于java - Server EndPoint for WebSocket Java API 中的 volatile 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48099722/

相关文章:

java - 通过 Hamcrest 断言集合中匹配元素的数量

java - 为什么 java 中的 collection.toArray() 不支持自动装箱

java - 为什么在我将组件添加到 JFrame 而不是将它们添加到 JPanel 后,所有这些组件都消失了?

python - args 的语义传递给 python threading.Thread __init__

django - 与 Django Channels 的 React native Websocket 连接已打开,但没有消息通过

java - 在每个标点符号之间插入空格

java - 设置 TextSpinner 适配器

java - 您可以将同步成本推到一个线程上吗?

sockets - 什么是 Socket.IO 发送和获取数据(确认)?

asp.net - SignalR WebSockets 在本地工作但不在服务器上