Java 类中的单个静态字段

有一个类 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@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.clients.jedis.JedisPool@3d11fc5d

redis.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]);

                }


慕桂英546537
浏览 158回答 3
3回答

婷婷同学_

你在做什么被称为“双重检查锁定”。如果您在 Stackoverflow 或 Google 上搜索它,您会发现许多解释为什么它在 Java 中无法正常工作。替代方案是:如果你很可能会在它的持有类被加载时使用这个对象,那么只需直接初始化它并使该字段成为最终的。声明字段volatile。使用一个持有类,即有一个私有的内部类来持有该字段,然后创建final。

12345678_0001

我想到的唯一补充是删除synchronized初始化并直接使用static-holder-pattern。从最上面的答案:JVM推迟初始化 InstanceHolder 类,直到它被实际使用,并且因为 Singleton 是用静态初始化器初始化的,所以不需要额外的同步。这可以在您的代码中使用,如下所示:public class RedisLogger{&nbsp; &nbsp; &nbsp;public static JedisPool getJedisPool(){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return JedisPoolHolder.INSTANCE;&nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp;private static final class JedisPoolHolder{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;private static final JedisPool INSTANCE = new JedisPool();&nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp;// the rest of your code}

ibeautiful

您可以直接为变量赋值并final static在您的情况下声明它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java