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 线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

Jetty 8.1.1 Websocket 客户端握手

Jetty:套接字连接作为 websocket 连接

如何让 eclipse-jetty 插件扫描和识别 websocket 类?

在类路径中添加库后找不到 Jetty WebSocket 类

Jetty9 WebSocket 客户端 - SessionFactory.createSession 导致 java.lang.NullPointerException

让 Jetty Websocket 使用与 JavaScript Websocket 相同的语言