套接字对象

时间:2017-11-03 19:29:48

标签: java multithreading locking synchronized

我有一个下面的代码,我在套接字上使用synchronized:

public boolean send(final long addr, final byte[] enc, final Socket socket) {
    ZMsg msg = new ZMsg();
    msg.add(enc);    

    // using the socket as its own lock while accessing it
    boolean sent;
    synchronized (socket) {
        sent = msg.send(socket);
    }
    msg.destroy();
    retryHolder.put(addr, enc);
    return sent;
}

我想了解套接字上的synchronized如何在这里工作?我有大约20个线程同时调用此send方法,每次Socket可能不同。我们有大约60个套接字可供选择,所以这20个线程都可以从60中选择任何一个套接字。有可能,多个线程可以选择相同的套接字来发送数据,或者多个线程可以每次选择不同的套接字来发送数据。以下是我能想到的情景:

  • 所有20个线程每次都选择不同的套接字来发送数据,因为我们有60个套接字可供使用。那么套接字上的synchronized如何在这种情况下工作?是快还是会阻塞任何线程?
  • 在20个线程中,有些线程选择相同的套接字来随机发送数据。因此,所有这些线程都会在进入synchronized块之前等待其他线程,这意味着每个线程都在等待该套接字被释放?它会减慢任何速度吗?
  • 我错过了任何其他案例?

基本上我想弄清楚,使用socket关键字对我可以遇到的所有场景使用synchronized作为锁定是否会有任何性能损失。

2 个答案:

答案 0 :(得分:1)

这种机制可以防止不同的线程同时将数据发送到同一个套接字并破坏您的数据。使用不同套接字的不同线程不会阻塞,虽然同步行为不是“免费”,但与通过网络发送数据相比,它可以忽略不计。

答案 1 :(得分:0)

  1. 如果每个线程的套接字都不同于其他线程。表现不会受到阻碍。因为没有线程会被阻塞以锁定套接字。
  2. 假设三个线程有相同的套接字。只允许一个在socket上发送数据。一旦完成锁定将被释放,下一个线程将获得套接字的锁定并开始发送数据,然后是第三个线程,依此类推。所以这里会有一些性能影响。正如您所提到的,与套接字相比,线程数量较少。我建议只有在已经分配了所有套接字以避免任何性能问题时才更改实现以将相同的套接字分配给线程。
  3. 但是,如果socket类是你自己的类,你可以更改代码。最好在send方法上添加同步,或者最好在所有方法上添加同步,以便没有其他线程可以在没有锁的情况下使用它。如果你不能改变它,你可以为Socket类创建包装类或代理,并使代理类中的方法同步。