`
小懒蛋
  • 浏览: 31148 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java 静态代码块只在类加载时执行一次

    博客分类:
  • java
 
阅读更多

java 类中的静态域的初始化和静态代码块的执行只在类加载的时候执行且只执行一次。

仅执行一次,所以这一定是线程安全的,由此引出的在单例设计模式中采用静态内部类中的静态域存储唯一一个实例,既保证了线程安全又保证了懒加载,此技术被称作(initialization on demand holder)。但不在本文讨论范围。

本文旨在验证静态代码块只执行一次,即线程安全。

 

我需要设计一个类,静态代码块需要执行较长时间,然后在测试方法中以多线程的方式触发此类的加载,然后检验结果,验证线程安全。

 

本人才疏学浅,如有错误请不吝赐教。

另外请尊重别人的劳动成果,如需转载请注明出处:

 http://waitingkkk-163-com.iteye.com/blog/2231416

 

需要“较长时间加载”的类:

public class SlowInit {
    static{
        System.out.println(Thread.currentThread().getName() + " class SlowInit begin to init static block");
        try{
            TimeUnit.SECONDS.sleep(5);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " class SlowInit static block init over");
    }

    public static void say(){
        System.out.println(Thread.currentThread().getName() + " say: hi~" );
    };
}

 

测试类:

public class ConcurrencyTest {

    private static CountDownLatch startGate = new CountDownLatch(1);

    public static void main(String args[]){
        for(int i=0; i<100; i++){
            new Thread(task).start();
        }
        startGate.countDown();
    }

    private static Runnable task = new Runnable() {
        @Override
        public void run() {
            try {
                startGate.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            SlowInit.say();
        }
    };
}

 

测试类中采用CountDownLatch技术模拟100个线程同时启动,然后都会触发SlowInit类的类加载。

测试结果如下:

Thread-33 class SlowInit begin to init static block
Thread-33 class SlowInit static block init over
Thread-33 say: hi~
Thread-96 say: hi~
Thread-91 say: hi~
Thread-87 say: hi~
Thread-97 say: hi~
Thread-77 say: hi~
Thread-1 say: hi~
……
……
……

 可以发现,只有一个线程可以触发类的加载过程,且在此类加载过程中,其他线程处于阻塞状态, 等待类加载的完成。

即:

java 静态代码块只在类加载时执行一次

分享到:
评论
1 楼 firfor 2018-07-18  
对于一个类加载器,或者是多个类加载器,最终由一个 define class loader 进行加载的话.这里的代码执行一次是正确的.反之,可能会执行多次.

相关推荐

    java 静态代码块通过类加载器获取资源文件例子

    因为静态代码块只执行一次,所以这种方式避免了每次创建类实例时都去读取资源文件的开销。例如: ```java public class AppConfig { static { InputStream inputStream = AppConfig.class.getResourceAsStream("/...

    java静态代码块与非静态代码块参照.pdf

    它的特点是:在类加载时自动执行的,且只执行一次。静态代码块通常用于初始化一些项目最常用的变量或对象。 在上面的实例代码中,静态代码块被定义在类的最顶层,且使用 static 关键字修饰。静态代码块中的代码在类...

    java静态代码块与非静态代码块.doc

    静态代码块是在类加载时自动执行的,通常用于初始化一些项目最常用的变量或对象,而非静态代码块是在创建对象时自动执行的,通常用于初始化对象的状态。同时,静态方法和静态代码块也有一些区别,静态方法需要被调用...

    java 代码块与静态代码块加载顺序

    Java 代码块与静态代码块加载顺序详解 Java 代码块与静态代码块加载顺序是 Java 语言中一个重要的概念,理解这两个概念对于编写高效、可靠的 Java 代码至关重要。本文将详细介绍 Java 代码块与静态代码块加载顺序的...

    Java静态代码块作用及执行顺序解析

    Java静态代码块是Java语言中的一种特殊代码块,它们在类加载的时候执行,且只执行一次。它们通常用来初始化静态变量、设置静态变量的初始值等。静态代码块的作用域是整个类,而不是某个对象实例。 静态代码块的执行...

    Java的静态代码块、非静态代码块、构造函数

    静态代码块只执行一次,即使类有多个实例。 接着,我们讨论非静态代码块,也称为实例初始化块。这种代码块在创建类的每个新实例时执行,用于初始化对象的状态。非静态代码块可以包含任意Java代码,但通常用于设置...

    Java常见笔试、面试题目深度剖析,方法重写详解、静态代码块与构造方法执行顺序问题

    静态代码块通常用来初始化类级别的变量,或者执行一些仅需执行一次的设置操作。静态代码块的执行顺序取决于它们在源码中的出现顺序。 接下来,我们将探讨**构造方法执行顺序**。在创建一个对象时,构造方法负责初始...

    Java静态代码块加载驱动代码实例

    Java静态代码块加载驱动代码实例 Java静态代码块是一种特殊的代码块,它可以在类加载时被执行,该代码块只能被加载一次,无论new多少个对象。静态代码块通常用来加载配置文件、初始化操作等。 在Java中,静态代码...

    Java:静态代码块和构造函数执行顺序

     1 静态变量,静态代码块(类加载时执行,类不加载不执行)  2 实例变量,实例代码块(创建对象时才执行,不创建对象不执行)  3 构造函数,(创建对象时执行完2后再执行构造函数,不管构造函数是public还是private...

    Java基础之代码块.docx

    静态块是指写在类中方法外的静态代码块,这种代码块的执行时机是类加载时。例如: ```java public class Demo01 { static { System.out.println("这是静态代码块"); } } ``` 在上面的代码中,静态块是写在 `Demo...

    关于Java中静态代码块的执行浅析

    Java中的静态代码块是一种特殊的代码块,它们是在类加载过程中执行的,而不是在对象创建时执行的。静态代码块的执行是自动的,且只执行一次。在Java中,静态代码块的执行是static关键字的结果。 静态代码块的执行...

    java代码-日常练习33,代码块### 静态代码块 static{代码内容;} 随着类的加载就执行一次 构造器代码块 {代码内容;} 每创建对象就执行一次 局部代码块 {代码内容;} 方法执行一次执行一次

    静态代码块由`static`关键字标识,它是在类被加载到Java虚拟机(JVM)时执行的,且只会执行一次。静态代码块通常用来初始化类级别的变量,因为它在任何对象实例化之前就已经运行。这样的设计使得程序员可以在不创建...

    Java面向对象(高级)- 类的成员之四:代码块

    静态代码块由`static`关键字修饰,它们在类加载时执行,且只执行一次。静态代码块通常用于初始化静态变量,可以包含输出语句,但不能直接访问非静态成员。如果有多个静态代码块,会按照它们在源码中的顺序依次执行。...

    java 静态块实例块构造器调用

    它们在类加载时执行,且只执行一次。无论创建多少个类的实例,静态块只会被执行一次。这是因为在Java中,类的静态成员是与类相关的,而非类的实例。 ```java public class Parent { static { System.out.println...

    Java类动态加载(一)——java源文件动态编译为class文件

    这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...

    Java静态初始化块和对象初始化块

    静态初始化块是以`static`关键字标识的代码块,它在类被加载到Java虚拟机(JVM)时执行,且只执行一次。静态初始化块常用于设置类级别的变量,或者执行只应执行一次的初始化操作。例如,如果一个类需要在程序运行前...

    Java中的静态变量静态方法静态块与静态类.docx

    静态块是由一些语句组成的段落,它在类被加载进内存时执行,且无论类被使用多少次它都只会执行一次。一个类的静态块可以有多个,其执行顺序由它在代码中的顺序决定。 在静态块中,我们通常进行一些需要进行异常捕获...

    JAVA程序:静态块代码

    它是类加载时执行的,且只执行一次。在理解静态块之前,我们需要先了解类加载的过程和静态变量的概念。 静态变量是属于类的,而不是类的实例对象。这意味着,无论创建多少个对象,静态变量在内存中只有一个副本,...

    Java 中普通代码块,构造代码块,静态代码块区别及代码示例

    静态代码块在类加载时仅执行一次,且先于非静态成员的初始化。如果一个类中有多个静态代码块,它们会按照在源码中的顺序依次执行。需要注意的是,静态代码块不能访问非静态成员,因为它们在类实例化之前执行,此时...

    Java static静态初始快

    父类的静态初始化块只在父类加载时执行一次。 6. **使用场景**:常用于设置静态变量的初始值,创建静态对象,或者执行一次性的系统设置操作。 在实际开发中,合理使用静态初始化块可以提高代码的组织性和效率。...

Global site tag (gtag.js) - Google Analytics