【问题标题】:Is Jetty websocket client class WebSocketClient thread safe?Jetty websocket 客户端类 WebSocketClient 线程安全吗?
【发布时间】:2016-11-30 21:08:23
【问题描述】:

码头 9.3

Java 8

org.eclipse.jetty.websocket.client.WebSocketClient 线程安全吗?

多个线程是否可以使用此类的单个实例来创建 websocket 会话(使用connect 方法)?

【问题讨论】:

    标签: java websocket jetty client jetty-9


    【解决方案1】:

    不是,the code 至少有一个例子:

    WebSocketClient 的目的是提供一种与远程 websocket 端点建立连接的方法。

    这是通过调用connect() 方法实现的,该方法返回Future Session。好吧,现在想象一下

    1. 线程 1 实例化 WebSocketClient 并调用 setCookieStore()

    2. 线程 1 调用 connect(Object websocket, URI toUri)

    3. connect()内部线程1执行

      ClientUpgradeRequest request = new ClientUpgradeRequest(toUri)
      

      request.setRequestURI(toUri)
      
    4. 线程 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 绝对是线程安全的。 代码有时可能包含错误这一事实并不意味着这不是多线程代码。
    猜你喜欢
    • 2019-03-20
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    相关资源
    最近更新 更多