在我的WebSocket应用程序中,我有包含在会话之间共享的数据的集合 - 每个会话都可以访问集合中的所有数据。我通过简单地使集合静态来实现这一点。
我从网上阅读的理解是WebSockets(在我的案例中运行在Tomcat 8上)遵循单线程模型,因为每个会话都有一个单独的线程。所以......
我的问题是; 我应该让共享成员同步,因为任何WebSocket线程都可以访问它们吗?
或者WebSockets是否为我处理这个问题?
我假设我应该同步所有共享的内容,但只是确认!感谢。
答案 0 :(得分:4)
如果您有多个线程读取可能同时写入(更新)的共享集(或任何非线程安全变量),那么需要同步他们。 Java 8向synchronizedSet
添加了一个新的Collections
方法(请参阅Collections.synchronizedSet)。在Java 8之前,您提供自己的同步。有关创建Java 8 synchronizedSet
的更多信息,请参阅此documentation。
即使使用Websockets,也需要同步,因为您已经定义了可以同时由多个Set
会话访问的静态数据(websocket
)。实例数据(非静态变量)不需要同步,因为单线程模型保证您的类(在同一会话中)不能同时执行两个方法。可以在此Oracle documentation中找到有关每个Websocket会话的一个线程的信息。具体来说它说:
与servlet相反,WebSocket端点被多次实例化。容器为每个与其部署URI的连接创建一个端点实例。 每个实例 仅与一个连接相关联。此行为有助于保持每个连接的用户状态并简化开发,因为在任何给定时间只有一个线程正在执行端点实例的代码。
因此每个实例变量(非静态)不需要特殊的同步。 Websockets保证单线程模型中的线程安全。但是,这不适用于这些实例之间的共享数据(静态变量)。因为它们可能在自己的线程中运行,所以需要在适当的时候提供同步。