Java静态初始化器参考子类:避免类加载死锁。

11

我有一个类ItemType,其中包含引用子类实例的final static字段:

public static final ItemType DURATION = new BuiltInAtomicItemType(x);

static class BuiltInAtomicItemType extends ItemType {

    public BuiltInAtomicItemType(X x) {
        this.x = x;
    }

如果一个线程首先加载了超类而另一个线程首先加载了子类,则会引发类加载死锁的可能性。

现在的问题是,这是一个公共API,我不能轻易更改它。我想消除类加载死锁的可能性,但我不想强制更改引用ItemType.DURATION或其他40多个类似字段的应用程序。

有没有一种方法可以避免潜在的死锁,同时保留公共API?


这两个类(其中一个是另一个的成员)被不同的类加载器加载的可能性有多大? - ernest_k
我们偶尔会收到这样死锁的报告 - 也许每年只有一个,来自一个庞大的用户社区。从统计学上来说,这是一个小问题,但我不喜欢告诉用户“有时这些事情就会发生”。 - Michael Kay
我猜你应该把这个问题提交给Oracle...听起来更像是编译问题...我的意思是,代码没有任何问题。它都是合法的。 - Victor
静态初始化程序中的死锁是一个众所周知的问题,例如请参见https://www.farside.org.uk/201510/deadlocks_in_java_class_initialisation。我的问题是如何更改我的代码以避免已知的问题。 - Michael Kay
1个回答

4

状态报告:似乎没有人知道如何解决这个问题。在复杂应用程序中设计一个类结构,以避免在类加载和初始化期间发生死锁的可能性似乎非常困难。在不对公共API进行不兼容更改的情况下修改现有应用程序以消除此类可能性,在一般情况下似乎是不可能的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接