简体   繁体   English

Server EndPoint for WebSocket Java API中的易变变量?

[英]Volatile variables in Server EndPoint for WebSocket Java API?

Looking at other examples across the web, when a server endpoint is created by means of Java API for WebSocket, the shared variables among all EndPoint instances are defined as static, but not volatile. 查看网络上的其他示例,当通过Java API for WebSocket创建服务器端点时,所有EndPoint实例之间的共享变量都定义为静态,但不是易变的。 I would like to know the reason. 我想知道原因。

As I understand, the clients opening websockets will create a new thread in the server. 据我了解,打开websocket的客户端将在服务器中创建一个新线程。 So to be thread-safe, shouldn't be defined as volatile the shared variables among EndPoint instances? 因此,为了线程安全,是否不应将EndPoint实例之间的共享变量定义为volatile

ie Instead of: 即代替:

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

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

is not better this code?: 这段代码不是更好吗?:

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

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

You need to use the volatile keyword in cases in which a variable is modified by some thread, but may be read by a different one (and there aren't any other synchronization mechanisms in place). 如果某个变量被某个线程修改但可能被另一个线程读取(并且没有任何其他同步机制),则需要使用volatile关键字。

So the question is whether there is a scenario in which some thread changes the Set to a different one, and a second thread tries to access it. 因此,问题是是否存在某种情况,其中某个线程将Set更改为另一个Set ,而另一个线程尝试访问它。 For example, if some thread does this: endPoint = new HashSet<>() , while a different thread does this: endPoint.get(...) , then yes, the Set should be volatile . 例如,如果某个线程执行此操作: endPoint = new HashSet<>() ,而其他线程执行此操作: endPoint.get(...) ,则是, Set应该是volatile

However if the different threads use the same Set instance, then the endPoint reference doesn't change, and is "effectively final". 但是,如果不同的线程使用相同的Set实例,则endPoint引用不会更改,并且“有效地是最终的”。 In that case, there's no need to add the volatile keyword. 在这种情况下,无需添加volatile关键字。

So the short answer is "it depends", since we need to look at complete example to see whether the Set should be volatile. 因此,简短的答案是“取决于”,因为我们需要查看完整的示例以查看Set是否应该可变。 I do want to point out one thing though - the use of an CopyOnWriteArraySet seems a bit odd since modifications to the set would only create a modified copy in the context of the modifying thread (that's what copy-on-write means). 我确实要指出一件事-使用CopyOnWriteArraySet似乎有点奇怪,因为对集合的修改只会在修改线程的上下文中创建修改后的副本 (这就是写时复制的意思)。

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

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