Jetty websocket 客户端类 WebSocketClient 线程安全吗?
Posted
技术标签:
【中文标题】Jetty websocket 客户端类 WebSocketClient 线程安全吗?【英文标题】:Is Jetty websocket client class WebSocketClient thread safe? 【发布时间】:2016-11-30 21:08:23 【问题描述】:码头 9.3
Java 8
org.eclipse.jetty.websocket.client.WebSocketClient
线程安全吗?
多个线程是否可以使用此类的单个实例来创建 websocket 会话(使用connect
方法)?
【问题讨论】:
【参考方案1】:不是,the code 至少有一个例子:
WebSocketClient
的目的是提供一种与远程 websocket 端点建立连接的方法。
这是通过调用connect()
方法实现的,该方法返回Future Session。好吧,现在想象一下
线程 1 实例化 WebSocketClient
并调用 setCookieStore()
线程 1 调用 connect(Object websocket, URI toUri)
。
在connect()
内部线程1执行
ClientUpgradeRequest request = new ClientUpgradeRequest(toUri)
和
request.setRequestURI(toUri)
线程 2 执行 setCookieStore(CookieStore cookieStore)
那么线程1创建的请求可能有线程2的URI对应的cookies。
为了保证线程安全,对象的内部状态应该在整个连接过程中不可修改。
【讨论】:
不确定 WebSocketClient 中的 cookie Store 是否在这里设置应在不同调用之间共享的公共 cookie。每个请求的 cookie 应该在 ClientUpgradeRequest 上使用 setCookies 设置。 如果 cookieStore 旨在跨线程共享,则应将其声明为volatile
。否则,一个线程可能会更改该值,而另一个线程看不到更改。此外,我在课堂上没有看到如何保留两组 cookie:线程子集和每个线程子集之间的共享。此外,是否可以考虑将 cookie 分成两个子集的合理用例?【参考方案2】:
我不能保证WebSocketClient
是 100% 线程安全的,但我可以说它在一定程度上是线程安全的。
查看source code,我们看到私有方法initializeClient
是同步的:
private synchronized void initializeClient() throws IOException
并且connect
方法正在使用Executor
:
// Execute the connection on the executor thread
executor.execute(promise);
该类的文档没有说明线程安全,但是从connect
方法调用同步的initializeClient
方法和使用Executor
是支持某种形式的多线程的明显迹象.
== 编辑 ==
线程安全通常只针对某些类型的操作得到保证。例如,可以保证仅用于读取操作而不用于写入操作。这是定义线程安全条件的文档的作用。 Sergio Montoro 的评论是对的,如果一个线程在另一个线程使用对象的过程中修改了对象,就会发生奇怪的事情。在WebSocketClient
的情况下,线程安全当然至少受限于其他线程不修改对象,或者受限于WebSocketClient
内部状态的同步和一致修改。
【讨论】:
+1 WebSocketClient 绝对是线程安全的。 代码有时可能包含错误这一事实并不意味着这不是多线程代码。以上是关于Jetty websocket 客户端类 WebSocketClient 线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 eclipse-jetty 插件扫描和识别 websocket 类?
在类路径中添加库后找不到 Jetty WebSocket 类
Jetty9 WebSocket 客户端 - SessionFactory.createSession 导致 java.lang.NullPointerException