有一个类 RedisLogger.java 用于处理带有 redis 的记录器。在 RedisLogger.java 中,我jedisPool使用以下代码声明了一个静态 JedisPool 字段:private static JedisPool jedisPool;因为 JedisPool 是线程安全的 calss,我只想jedisPool在我的应用程序中使用以下代码实例化一次:public static JedisPool getJedisPool() { if(jedisPool == null) { synchronized (JedisPool.class) { if(jedisPool == null) { jedisPool = new JedisPool(); } } } return jedisPool;}我用这段代码来测试它。ExecutorService executor = Executors.newCachedThreadPool(); for(int i = 0; i < 1000; i++) { executor.execute(()->{ System.out.println(RedisLogger.getJedisPool()); }); }从输出看来效果很好:redis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5dredis.clients.jedis.JedisPool@3d11fc5d....但它真的能达到我的期望吗?因为在我的应用程序中有很多这样的地方。例如。private static Cluster getCluster() { if(cluster == null) { synchronized (Cluster.class) { if(cluster == null) { Builder builder = Cluster.builder(); for (int i = 0; i < MSConfig.SRCDOC_CASSANDRA_ADDRS().length; i++) { builder.addContactPoint(MSConfig.SRCDOC_CASSANDRA_ADDRS()[i]) .withPort(MSConfig.SRCDOC_CASSANDRA_PORT()[i]); }
3 回答
婷婷同学_
TA贡献1844条经验 获得超8个赞
你在做什么被称为“双重检查锁定”。如果您在 Stackoverflow 或 Google 上搜索它,您会发现许多解释为什么它在 Java 中无法正常工作。
替代方案是:
如果你很可能会在它的持有类被加载时使用这个对象,那么只需直接初始化它并使该字段成为最终的。
声明字段
volatile
。使用一个持有类,即有一个私有的内部类来持有该字段,然后创建
final
。
12345678_0001
TA贡献1802条经验 获得超5个赞
我想到的唯一补充是删除synchronized初始化并直接使用static-holder-pattern。从最上面的答案:
JVM推迟初始化 InstanceHolder 类,直到它被实际使用,并且因为 Singleton 是用静态初始化器初始化的,所以不需要额外的同步。
这可以在您的代码中使用,如下所示:
public class RedisLogger{
public static JedisPool getJedisPool(){
return JedisPoolHolder.INSTANCE;
}
private static final class JedisPoolHolder{
private static final JedisPool INSTANCE = new JedisPool();
}
// the rest of your code
}
添加回答
举报
0/150
提交
取消