代码之家  ›  专栏  ›  技术社区  ›  Cephalopod

Java:如何使用数组元素进行双重检查锁定?

  •  1
  • Cephalopod  · 技术社区  · 15 年前

    private boolean[] isInitialized = new boolean[COUNT];
    
    private void ensureInitialized(int i) {
        if (! isInitialized[i]) {
            initialize(i);
            isInitialized[i] = true;
        }
    }
    

    现在我想让它线程安全。我知道Java中的双重检查锁定是“teh 3vilness!!1“,但自从 ensureInitialized 可能经常被调用,我不希望它被同步。所以我想这样做:

    private boolean[] isInitialized = new boolean[COUNT];
    
    private void ensureInitialized(int i) {
        if (! isInitialized[i]) {
            synchronized (this) {
                if (! isInitialized[i]) {
                    initialize(i);
                    isInitialized[i] = true;
                }
            }
        }
    }
    


    一些子问题:

    • 制作 isInitialized
    • 数组元素被改变了,我怎样才能使那些不稳定?
    • 有没有更好的方法来做这件事?

    (还要注意,这是一个实例方法,因此静态初始化器将不起作用)

    2 回复  |  直到 15 年前
        1
  •  1
  •   Dewfy    15 年前

    请注意,双重检查的java实现被称为“断模式”,因为它被证明是失败的(例如,请参见 http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    static AtomicReferenceArray<Boolean> instance = 
       new AtomicReferenceArray<Boolean>(COUNT);
    
    private void ensure(int i)
    {
        if(!instance.get(i) )
        {
            synchronized(this){
            if( !instance.get(i) ){
               initialize(i);
               instance.set(i, true);
            }
        }
    }
    
        2
  •  3
  •   mindas    15 年前

    你也可以考虑使用 Suppliers.memoize(Supplier<T> delegate) guava library

    推荐文章