亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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條經驗 獲得超6個贊

您可以直接為變量賦值并final static在您的情況下聲明它。


查看完整回答
反對 回復 2021-08-13
  • 3 回答
  • 0 關注
  • 182 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號