Одно статическое поле в классе Java - PullRequest
0 голосов
/ 27 августа 2018

Существует класс RedisLogger.java, который имел дело с регистратором с помощью redis.В RedisLogger.java я объявил статическое поле JedisPool jedisPool, используя этот код:

private static JedisPool jedisPool;

Причина JedisPool является поточно-ориентированным вызовом, я хочу создать экземпляр 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]);
                }
                cluster = builder.withCredentials(MSConfig.SRCDOC_CASSANDRA_USERNMAE(), MSConfig.SRCDOC_CASSANDRA_PASSWORD())
                        .withProtocolVersion(ProtocolVersion.V4)
                        .withPoolingOptions(getPoolingOptions())
                        .withSocketOptions(getSocketOptions())
                        .withRetryPolicy(getRetryPolicy())
                        .withQueryOptions(getQueryOptions())
                        .build();
            }
        }
    }
    return cluster;
}

Спасибо !!!

Ответы [ 3 ]

0 голосов
/ 27 августа 2018

Единственное добавление, о котором я думаю, это отбросить инициализацию synchronized и сразу перейти к шаблону статического держателя .От top answer :

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 голосов
/ 27 августа 2018

То, что вы делаете, называется «двойной проверкой блокировки».Если вы выполните поиск в Stackoverflow или в Google, вы найдете много объяснений, почему он не работает должным образом в Java .

. Альтернативы:

  1. Если это такочень вероятно, что вы будете использовать этот объект, когда загружен его класс хранения, а затем просто инициализировать его напрямую и сделать поле финальным.
  2. Объявить поле volatile.
  3. Использовать класс храненият. е. иметь закрытый внутренний класс, который содержит поле, которое затем задается final.

. См. также следующие вопросы:

0 голосов
/ 27 августа 2018

Вы можете напрямую присвоить значение переменной и объявить его final static в вашем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...