【问题标题】:static class initializers - are there situations where one would need to synchronize?静态类初始化器 - 是否存在需要同步的情况?
【发布时间】:2013-03-17 17:06:42
【问题描述】:

我有一种情况,我想初始化一些静态的“常量”(即初始化后不修改)数据结构。我在“静态{}”代码块中执行此操作。是否保证此代码块永远不会被执行两次?在某些特殊情况下我需要同步吗?

更新:部分答案在Are Java static initializers thread safe?

问题仍然存在:如何多次执行静态初始化程序?这有关系吗?我猜它对于不同的静态“实例”运行不止一次,即。在不同的 webapp 上下文中并附加到不同的类加载器,这样它们就不会“看到”彼此。对吗?

【问题讨论】:

  • 每个静态初始化程序在每个初始化类的类加载器中只运行一次。这些初始化中的每一个都在静态字段的不同副本上运行。

标签: java static synchronization initialization


【解决方案1】:

JVM 保证所有类静态初始化块只被调用一次(当类第一次加载时)。由于它只会被调用一次,因此不需要任何同步代码,因为这与 Only Once 规则相矛盾。

查看here 了解有关类加载和静态类初始化器的更多信息。

引用该页面:

编译器实际上做的是在内部生成一个类初始化例程,该例程将所有静态变量初始化器和所有静态初始化器代码块按照它们在类声明中出现的顺序组合在一起。当类第一次加载时,这个单一的初始化过程会自动运行一次。   –大卫·弗拉纳根

【讨论】:

    【解决方案2】:

    我想初始化一些静态的“常量”(即初始化后不修改)数据结构

    将该变量设为最终变量。

    喜欢

    public static final CONSTANT = 10;
    

    您可以将该代码放在静态块中。它在类加载时执行一次。

    【讨论】:

    • 哪个变量?他说的是static {} 块,不是吗?
    • 是的。它更复杂。右侧抛出必须捕获的异常。但这不是问题。即使在简单分配的情况下,也可能存在并发问题...
    猜你喜欢
    • 2017-11-10
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多