• static块初始化


    参考

    静态块的执行时机

    每当发生以下事件之一时,ClassLoader 都需要加载 Class:

    • 静态成员变量由应用程序设置(应用程序是指包含静态块的类之外的代码)
    • 应用程序访问非最终静态成员变量
    • 应用程序调用静态方法
    • Class.forName("...")
    • 使用 Class.newInstance() 或通过 new 关键字创建实例

    由于静态块的使用是在类的初始化/加载中(应该只发生一次),因此该块被 JVM 视为“同步”块。只有当类状态为“未初始化”时,线程才能访问此代码块。由于有多个上述事件可以触发类加载,JVM 需要确保类加载/初始化只发生一次。为了确保这一点,每个类都有一个“初始化锁”,它由首先到达静态块的线程获取,并且只有在静态块代码执行完成后才会释放锁。

    在此之前,其他线程在任何活动上都会被阻塞,例如尝试加载类或创建实例。一旦锁被释放,类的状态被设置为“完全初始化”,不需要任何其他线程进入静态块。

    初始化锁举例

    Test.java

    public class Test {
        static {
            System.out.println("Entered static block by thread " + Thread.currentThread().getName());
            try {
                Thread.sleep(10000);
                System.out.println("Finished static block by thread " + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    Main.java

    public class Main {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.submit(() -> Class.forName("org.priya.Test"));
            executorService.submit(() -> {
                final Test test = new Test();
                System.out.println("Object created by thread " + Thread.currentThread().getName());
            });
        }
    }
    

    初始化锁导致的死锁

    当一个类中的静态块代码触发另一个类的类加载事件,那个类中也有一个静态块,静态块又依赖于当前类,就会引入死锁,导致java.lang.ClassNotFoundException异常。

    死锁代码

  • 相关阅读:
    从零开始实现微信机器人
    简单易用的字符串模糊匹配库Fuzzywuzzy
    社会工程学框架
    数据结构【基础知识点总结】
    Go数组
    python generator与coroutine
    Flask开发系列之数据库操作
    【渗透技巧】资产探测与信息收集
    Appium Desktop Inspector 安卓真机配置(Windows)
    JAVA Random 随机类
  • 原文地址:https://www.cnblogs.com/wuu02/p/16059024.html
Copyright © 2020-2023  润新知