【问题标题】:Can other methods be called after finalize()?finalize() 之后可以调用其他方法吗?
【发布时间】:2016-10-14 06:57:00
【问题描述】:

如果我有

public class Foo {
    private boolean finalized = false;

    public void foo() {
        if (finalized)
            throw new IllegalStateException("finalize() has been called.");
    }

    @Override public void finalize() {
        super.finalize();
        finalized = true;
    }
}

是否保证,即使面对多个线程,假设只有 GC 会调用finalize(),IllegalStateException 永远不会被抛出?

我知道,面对导致对象不可垃圾回收的finalize() 方法,该对象不会被垃圾回收,并且可能会调用其他方法。但是这个finalize() 并没有这样做。 foo() 是否还有可能在finalize() 之后被调用?

【问题讨论】:

  • 您的意思是要问,'在 GC 调用 finalize 之后?'否则,某些白痴可能会明确要求您这样做。
  • @bmargulies 谢谢,这就是我的意思。
  • 您应该按照 Object not public 中最初定义的方式保护此方法以限制风险

标签: java finalize


【解决方案1】:

完全有可能一个不同的对象引用了Foo 的实例同时被最终确定——并且可能复活Foo 对象,允许它被使用定稿后。这有点粗鲁,但肯定会发生。

即使没有复活,另一个终结器也可以从其终结器调用Foo.foo():

public class Bar {
    private final Foo foo;

    @Override protected void finalize() {
        // The finalizer in foo may already have executed...
        foo.foo();
    }
}

【讨论】:

    【解决方案2】:

    正如 Jon Skeet 所提到的,完全有可能在一个线程当前处于终结过程中时调用方法。

    为了防止这种情况,您当然可以使代码线程安全。

    public class Foo {
        private boolean finalized = false;
    
        public void foo() {
            synchronized (this)
            {
                if (finalized)
                    throw new IllegalStateException("finalize() has been called.");
            }
        }
    
        @Override public void finalize() {
    
            synchronized (this)
            {
                super.finalize();
                finalized = true;
            }
        }
    }
    

    注意:为了格外小心,我会将对 super.finalize() 的调用放在 try/finally 块中:

    @Override public void finalize() {
    
            synchronized (this)
            {
                try
                {
                    super.finalize();
                }
                finally
                {
                    finalized = true;
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2015-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多