为什么IdleConnectionMonitorThread需要同步

why IdleConnectionMonitorThread need to synchronize

我在 'run' 的实现中看到许多使用 'synchronized' 的 IdleConnectionMonitorThread 示例。在我看来,这没有任何意义。

中的工具

edu.uci.ics crawler4j 4.2

public class IdleConnectionMonitorThread extends Thread {

  private final PoolingHttpClientConnectionManager connMgr;
  private volatile boolean shutdown;

  public IdleConnectionMonitorThread(PoolingHttpClientConnectionManager connMgr) {
    super("Connection Manager");
    this.connMgr = connMgr;
  }

  @Override
  public void run() {
    try {
      while (!shutdown) {
        synchronized (this) {
          wait(5000);
          // Close expired connections
          connMgr.closeExpiredConnections();
          // Optionally, close connections that have been idle longer than 30 sec
          connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
        }
      }
    } catch (InterruptedException ignored) {
      // terminate
    }
  }

  public void shutdown() {
        shutdown = true;
        synchronized (this) {
            notifyAll();
        }
        log.warn("newPosition: shutdown idleMonitorThread");

    }

}

由于大多数情况下我们只有一个IdleConnectionMonitorThread,并且这样使用,所以synchronized(this)没有任何意义。

IdleConnectionMonitorThread idleConnectionMonitorThread = new IdleConnectionMonitorThread(poolingHttpClientConnectionManager)

我想知道使用'synchronized'的好处,可以这样使用实现运行(删除synchronized)

      @Override
      public void run() {
        try {
          while (!shutdown) {
              wait(5000);
              // Close expired connections
              connMgr.closeExpiredConnections();
              // Optionally, close connections that have been idle longer than 30 sec
              connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
          }
        } catch (InterruptedException ignored) {
          // terminate
        }
      }

阅读 Object.wait(long)javadocs

如果在没有持有正在等待的互斥锁时调用它,则会出现异常。 javadoc 指出:

Throws: IllegalMonitorStateException - if the current thread is not the owner of the object's monitor.

一般来说,在 "wait/notify" 协议中锁定互斥量对于确保正在管理的共享状态对所有参与的线程可见是必不可少的。在这种情况下,shutdown 变量被声明为 volatile,所以这不是问题。但是,"wait/notify" 协议 无论如何都需要 锁定;见上文。

I wonder the benefit of using synchronized, can use implement run in this way (delete the synchronized).

没有。如果你删除了 synchronized 你会得到一个例外。但是您可以将 Object.wait(...) 替换为 Thread.sleep(...) ... 然后 synchronized 就没有必要了。


至于"oddness"这段代码,谁知道作者为什么会这样。但这真的重要吗?有一个工程原理:"If it ain't broken, don't fix it"。没有人提出此代码被破坏的原因。