MulticastSocket加入/离开组,发送,接收线程安全

时间:2018-01-15 14:13:30

标签: java multithreading thread-safety multicast

我在我的应用程序中推理了多播套接字线程安全性。首先,我有多个线程共享同一个多播套接字实例,该多播套接字用于连接同一端口上的不同组。以下是我的问题:

  1. 是否必须同步对joinGroup()leaveGroup()方法的调用?
  2. 是否必须同步调用send()receive()方法,这些方法始终使用新的数据报包作为参数?
  3. 这是第二个问题的代码示例:

    /* SEND METHOD EXAMPLE. */
        DatagramPacket sndPckt = new DatagramPacket(buf, buf.length, groupAddr,port);
        try{
            multicastSocket.send(sndPckt);
        } catch (IOException e) {
            /* Error handling. */
        }
    /* RECEIVE METHOD EXAMPLE. */
        DatagramPacket recv = new DatagramPacket(buf, buf.length);
            try{
                multicastSocket.receive(recv);
            } catch (IOException e) {
                /* Error handling. */
            }
    

    我找到了ArrayList,但它谈到了使用相同的Datagram Packet。 我也测试了我的应用程序,但我没有发现任何竞争条件或不一致但我不能100%确定使用是线程安全的。

2 个答案:

答案 0 :(得分:2)

javadocs没有说明MulticastSocket是否是线程安全的,但是阅读源代码表明它是。

  1. joinGroup()leaveGroup()方法是native调用的包装器,它们(反过来)是系统调用的包装器。所有系统调用都是线程安全的,至少就内核空间中保存的数据而言。 (如果不是,那将是一个潜在的安全漏洞。)我对代码的阅读是joinGroup()leaveGroup()不更新任何用户空间数据。

  2. send()receive()方法在DataPacket个参数上同步,以确保使用相同DataPacket的两个线程可以安全地执行此操作。除了数据包对象之外,这些方法不会更新用户空间中的任何共享套接字状态,并且(如上所述)我们可以假设内核空间数据是线程安全的。

  3. EJP认为这些系统调用是原子的(按设计),因此是线程安全的。这是正确的 1 。但是,还需要考虑用户空间中的线程安全性(即系统调用之前和之后,或者当两个系统调用共享用户空间缓冲区时)。

    1 - 至少我的理解。我找不到一个明确的来源,说明哪些系统调用是原子设计的。

答案 1 :(得分:2)

  

我是否必须同步调用joinGroup()和leaveGroup()方法?

没有

  

我是否必须同步调用send()和receive()方法,这些方法总是使用新的数据报包作为参数?

没有

  • DatagramSocket读取和写入彼此独立。
  • DatagramSocket写入在操作系统级别是原子的,因此它们是线程安全的。
  • DatagramSocket读取由Java同步,它们也是 操作系统级别的原子,所以它们再次是线程安全的。
  • MulticastSocketDatagramSocket继承其I / O方法。
  • joinGroup()/leaveGroup()在操作系统级也是原子的。

为免我被指控plagiarism我将声明该链接本身是我最初几十年前在Sun Java论坛上撰写的未经授权的材料副本。