为了账号安全,请及时绑定邮箱和手机立即绑定

Java 类中的单个静态字段

Java 类中的单个静态字段

慕桂英546537 2021-08-13 16:50:05
有一个类 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 中无法正常工作

替代方案是:

  1. 如果你很可能会在它的持有类被加载时使用这个对象,那么只需直接初始化它并使该字段成为最终的。

  2. 声明字段volatile

  3. 使用一个持有类,即有一个私有的内部类来持有该字段,然后创建final


查看完整回答
反对 回复 2021-08-13
?
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

}


查看完整回答
反对 回复 2021-08-13
?
ibeautiful

TA贡献1993条经验 获得超5个赞

您可以直接为变量赋值并final static在您的情况下声明它。


查看完整回答
反对 回复 2021-08-13
  • 3 回答
  • 0 关注
  • 157 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信