java - 确保 "singleton-like"非final字段的唯一性,在哪里加锁?

标签 java multithreading locking singleton synchronized

我希望 JdbcPersistenceManager 始终只有一个 jdbcConnection 并通过以下方式实例化它:JdbcConnectionManager.getJdbcConnection()

这是一个简单的模式,取自 (​​2004-11-01 | Head First Design Patterns | O'Reilly Media | 688p | by Elisabeth Freeman | ISBN-0596007124),可能被误用、误解和不合适。

synchronized() 应该锁定“this”还是专门用于跟踪锁定的特定新(静态?)字段?我该怎么做?

public class JdbcPersistenceManager implements PersistenceManager {
  private volatile Connection jdbcConnection;
  /* ... */
  private Connection getJdbcConnection() throws JdbcConnectionFailureException {
    if (jdbcConnection == null) {
      synchronized (this) {
        if (jdbcConnection == null) {
          jdbcConnection =
              JdbcConnectionManager.getJdbcConnection(jdbcConnectionParameters);
        }
      }
    }
    // label:here
    return jdbcConnection;
  }
}

假设 jdbcConnection 实例化,即使在标记为“label:here”的点(如果我们愿意),只是为了论证,如何最好地检查连接是否仍然有效,如果不有效则重新创建它?

连接池不是我想要在这里做的。只有一个连接...如果它是“空”或“无效”,则重新生成/重新打开它。

编辑:

我想要 getJdbcConnection 做的是:

1) 提供 jdbcConnections,确保在任何给定时间仅存在其中一个(不应允许客户端保留对 2 个不同连接的引用)

2) 如果由于某种原因关闭了“私有(private) volatile 连接 jdbcConnection”字段,则重新生成(即重新调用 JdbcConnectionManager.getJdbcConnection())

(例如,客户端 1 出现,获得连接,但关闭它,客户端 2 出现,连接不为空,但无法使用,因此她得到再生的)。

注意:我意识到没有什么可以阻止客户端 1 获得连接,而客户端 2 按照设计获得相同的连接,并在客户端 1 通过他的引用关闭连接后一毫秒内使用它......我不知道这是否可以解决?

最佳答案

双重检查锁定应该在类上完成,而不是在 this 上完成:

if (jdbcConnection == null) {
  synchronized (JdbcPersistenceManager.class) {
    if (jdbcConnection == null) {
      jdbcConnection =
          JdbcConnectionManager.getJdbcConnection(jdbcConnectionParameters);
    }
  }
}

根据连接检查,您可以按照您的建议在创建后执行此操作。我不会递归地调用该方法,只需将 Connection 实例 null 并尝试再次调用 getJdbcConnection()

关于java - 确保 "singleton-like"非final字段的唯一性,在哪里加锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10963886/

相关文章:

Java 并发 : Threads notifications

multithreading - 同步线程以同时读取不同的资源

c# - 锁定一个winforms控件

java - 使用 .pfx 证书从 Apache Tomcat 8 调用 RESTFul API

java - 确认 SNS 订阅者的 HTTP 端点

java - Tomcat + JPA + MySQL : java. lang.NoClassDefFoundError: javax/persistence/Persistence

c# - 如何确保线程安全的 Web API 基础 Controller 方法

Java - IndexOutOfBoundsException

python - QObject::killTimers 错误 QThread PyQt

c++ - 锁定自由原子状态类 - 是否正确?