`
liuInsect
  • 浏览: 133412 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

java static块的执行次数

阅读更多

比较有意思的一段代码,可以先运行看效果再将注释取消后看运行效果,上代码

/**
 * 
 * 每个对象实例化的时候,都要路过static方法
 * 但是编译器会保证static快的执行是原子的,即便是多线程过来也要一个个执行
 * 只不过,只有第一个实例动作的时候static快内的代码被执行
 * 其他实例只是“路过”
 * 即,每个实例都要走到static块,但是static块只会执行一次,
 * 是通过调用该类的 client方法导致的,该方法只在类被加载的时候JVM调用
 * @author liuinsect
 *
 */
public class StaticBlockTest  implements Runnable{
	
	static{
		if(true){
			System.out.println("test");
//			while(true){
//				
//			}
		}
		
	}
	
	@Override
	public void run() {
		
		System.out.println("run");
	}
	
	/**
	 * @author liuinsect 	
	 * @date 2013-2-7
	 * @param args
	 */
	public static void main(String[] args) {
		StaticBlockTest s = new StaticBlockTest();
		StaticBlockTest s1 = new StaticBlockTest();
//		StaticBlockTest s2 = new StaticBlockTest();
//		StaticBlockTest s3 = new StaticBlockTest();
//		StaticBlockTest s4 = new StaticBlockTest();
//		StaticBlockTest s5 = new StaticBlockTest();
		Thread t1 = new Thread(s);
		Thread t2 = new Thread(s1);
		
		
		t1.start();
		t2.start();
		
	}



}

 

0
3
分享到:
评论
6 楼 liuInsect 2013-02-11  
smiky 写道
在类加载的init阶段,类的类构造器中会收集所有的static块和字段并执行,static块只执行一次,有JVM保证其只执行一次
* 初始化:
* 初始化过程是执行类构造器clinit()方法的过程
* 1. clinit里面的内容是合并static块与static变量组成,static块只能访问在它之前定义的static变量
* 2. 虚拟机保证父类的clinit会先于子类clinit执行,最先执行的clinit肯定是java.lang.Object的
* 3. 父类static字段会先赋值,这个2
* 4. 如果没有static块或节段,不会生成clinit
* 5. 对于接口,只有在子接口中使用到父接口中变量时,父接口才会初始化,接口实现类初始化时不会执行接口的clinit
* 6. 虚拟机保证多线程下只有一个线程能执行类的clinit,会被加锁与同步


不错,抄书抄得还可以
5 楼 smiky 2013-02-08  
在类加载的init阶段,类的类构造器中会收集所有的static块和字段并执行,static块只执行一次,有JVM保证其只执行一次
* 初始化:
* 初始化过程是执行类构造器clinit()方法的过程
* 1. clinit里面的内容是合并static块与static变量组成,static块只能访问在它之前定义的static变量
* 2. 虚拟机保证父类的clinit会先于子类clinit执行,最先执行的clinit肯定是java.lang.Object的
* 3. 父类static字段会先赋值,这个2
* 4. 如果没有static块或节段,不会生成clinit
* 5. 对于接口,只有在子接口中使用到父接口中变量时,父接口才会初始化,接口实现类初始化时不会执行接口的clinit
* 6. 虚拟机保证多线程下只有一个线程能执行类的clinit,会被加锁与同步
4 楼 runfriends 2013-02-07  
第一个线程还在static的时候,其实类加载工作还没有完成。其它使用该类的线程就要等待。以后再次使用这个类的时候,只要是同一个classloader加载的,static就不会再执行。

如果有其它classloader加载的类要使用这个类,而这个classloader的父加载器不是加载这个类的那一个,它就要再去加载一次这个类。
3 楼 a8hao 2013-02-07  
static代码块进入死循环后,正如你所说的,main函数事实都没有进去的机会了
2 楼 liuInsect 2013-02-07  
chenjingbo 写道
要过年啦.也没啥人了..哈哈..先预祝新年快乐

顺便说下这个代码我的看法,

你把几个概念弄混淆了..

static语句块,不是在实例化的时候被执行的,而是在jvm进行类加载的时候 被执行的..和你特意在main方法中实例化的两个对象没有任何关系.也和你特意开的线程没有任何关系..我说的理由如下

package zhenghui.test;

public class StaticBlockTest  implements Runnable{

    static{
        if(true){
            System.out.println("test");
//			while(true){
//
//			}
        }

    }

    @Override
    public void run() {

        System.out.println("run");
    }

    /**
     * @author liuinsect
     * @date 2013-2-7
     * @param args
     */
    public static void main(String[] args) {
//        StaticBlockTest s = new StaticBlockTest();
//        StaticBlockTest s1 = new StaticBlockTest();
////		StaticBlockTest s2 = new StaticBlockTest();
////		StaticBlockTest s3 = new StaticBlockTest();
////		StaticBlockTest s4 = new StaticBlockTest();
////		StaticBlockTest s5 = new StaticBlockTest();
//        Thread t1 = new Thread(s);
//        Thread t2 = new Thread(s1);
//
//
//        t1.start();
//        t2.start();

    }



}

直接运行,还是会打印 test..虽然没有创建任何这个对象..

			while(true){

			}

这段代码会在执行static语句块的时候进入死循环.其他没任何用..




同祝新年快乐, 我明白你的意思,不知是不是我没有表述清楚,再说明下,
static语句块确实是在类加载器加载该类的时候初始化的,确切的说,实在类加载器的第四个步骤:初始化 阶段执行的,所以和new 这个对象的关系是,当我在main函数中new这个对象的时候JVM去找这个类,加载进来执行到类加载器的最后一个步骤:初始化的时候执行的static里的语句,而你这里注释掉mian中的代码还会有test打印的原因在于,你main函数正好就是在当前的这个类中,你要执行main函数当然需要类加载器加载该类,当然也有就有static块的执行。


至于我用while循环,我想表达的意思是: 第一个线程还在static块中的时候,第二线程不能进入static块,从而,第二个线程里的所有其他方法也不能执行。

不知道我的描述有没有说清楚?
欢迎讨论~~~谢谢
1 楼 chenjingbo 2013-02-07  
要过年啦.也没啥人了..哈哈..先预祝新年快乐

顺便说下这个代码我的看法,

你把几个概念弄混淆了..

static语句块,不是在实例化的时候被执行的,而是在jvm进行类加载的时候 被执行的..和你特意在main方法中实例化的两个对象没有任何关系.也和你特意开的线程没有任何关系..我说的理由如下

package zhenghui.test;

public class StaticBlockTest  implements Runnable{

    static{
        if(true){
            System.out.println("test");
//			while(true){
//
//			}
        }

    }

    @Override
    public void run() {

        System.out.println("run");
    }

    /**
     * @author liuinsect
     * @date 2013-2-7
     * @param args
     */
    public static void main(String[] args) {
//        StaticBlockTest s = new StaticBlockTest();
//        StaticBlockTest s1 = new StaticBlockTest();
////		StaticBlockTest s2 = new StaticBlockTest();
////		StaticBlockTest s3 = new StaticBlockTest();
////		StaticBlockTest s4 = new StaticBlockTest();
////		StaticBlockTest s5 = new StaticBlockTest();
//        Thread t1 = new Thread(s);
//        Thread t2 = new Thread(s1);
//
//
//        t1.start();
//        t2.start();

    }



}

直接运行,还是会打印 test..虽然没有创建任何这个对象..

			while(true){

			}

这段代码会在执行static语句块的时候进入死循环.其他没任何用..

相关推荐

    Java零基础-static关键字.md

    - **执行次数:** 只执行一次。 - **应用场景:** 初始化类资源或配置信息。 #### 五、静态内部类 **定义与声明:** 静态内部类(也称为嵌套类)是定义在一个外部类中的类,使用`static`关键字声明。与普通内部类...

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

    静态代码块和非静态代码块的主要区别在于它们的执行时机和执行次数。静态代码块在类加载时执行一次,而非静态代码块在每次创建对象时执行一次。 在继承关系中,静态代码块的执行顺序是:父类静态代码块 -> 子类静态...

    Java练习题库(含答案及解析).pdf

    Java中的类可以包含不同的成员,包括字段(变量)、方法、构造方法、块(代码块)和内部类。Java类的成员访问权限决定了它们可以被其他类访问的范围。 Java的继承机制允许一个类(子类)继承另一个类(父类)的属性...

    JAVA中的鼠标双击事件

    // 记录定时器执行次数 public void run() { if (MyMouseListener.flag) { // 如果双击事件已经执行,那么直接取消单击执行 n = 0; MyMouseListener.clickNum = 0; this.cancel(); return; } if (n == 1) ...

    JAVA习题及实验-电子工业大学出版!

    2. `public static void main(String args[])` 是Java程序的入口点,程序从这里开始执行。 3. `int i=1, n=10, s=0;` 分别声明并初始化了三个整型变量,`i`作为循环计数器,`n`为要累加到的数,`s`用于存储累加的...

    java习题集+答案

    for循环提供了一种在给定次数内重复执行代码块的方式,而while循环则在条件为真时持续执行代码块。 Java的类(class)是一种自定义数据类型,它定义了对象的属性和方法。例如,String类是Java中最常用的类之一,它...

    熟悉java开发.docx

    编译过程由IDE自动完成,只需运行项目,IDE会查找主类(包含`public static void main(String[] args)`方法的类)并执行程序。 【Java基本数据类型】 Java的基本数据类型包括整型(byte, short, int, long)、浮点...

    JavaSE024static与final使用陷阱续..pdf

    在这种情况下,"P static block"和"Q static block"都会在类加载时执行一次,而构造方法会根据创建的实例数量执行相应次数。 总结一下,`final`关键字用于创建不可修改的变量,确保数据的不变性,而`static`关键字...

    java练习题大全

    1. Java语言的优点和特点之一是多线程,这允许Java程序能够并行执行多个任务。Java的多线程机制是Java语言的强大功能之一,它支持并发执行,可以创建多个线程共同完成一项任务。 2. 在Java中,类的声明需要遵守一定...

    Static关键字详解.docx

    Static关键字在Java编程语言中扮演着至关重要的角色,它允许我们创建类级别的变量和方法,这些变量和方法不依赖于类的实例即可访问。在深入理解Static关键字之前,我们需要了解类和对象的概念。类是创建对象的蓝图,...

    Java鼠标双击事件.

    // 记录定时器执行次数 public void run() { if (MyMouseListener.flag) { // 如果双击事件已经执行,那么直接取消单击执行 n = 0; MyMouseListener.clickNum = 0; this.cancel(); return; } if (n == 1) {...

    java机考题

    你可以使用ActionListener监听用户的选项选择,并根据选择执行相应操作。例如,当选择下拉框中的某个尺寸选项时,通过setPreferredSize方法改变JFrame的大小;当选择单选按钮时,通过setBackground方法改变窗口的...

    java笔记.txt

    根据提供的文件信息,我们可以从中提炼出关于Java... - `switch`: 根据不同的条件执行不同的代码块。 以上是Java基础学习过程中非常重要的知识点,通过理解并掌握这些内容,可以为后续深入学习Java打下坚实的基础。

    java开发spark程序

    接着,我们将创建一个简单的Spark Java程序,它执行一个基本的Word Count任务。这个任务会读取输入文本,计算每个单词出现的次数。 ```java import org.apache.spark.SparkConf; import org.apache.spark.api.java....

    java单词java单词.doc

    * For:已知次数循环,用于表示 Java 循环语句。 * Continue:结束本次循环进行下次跌代,用于表示 Java 循环语句中的跳过语句。 * Length:获取数组元素个数,用于表示 Java 数组的长度。 第三章:面向对象编程 *...

    最新Java面试题

    - **Java异常处理`try-catch-finally`的执行过程**:首先尝试执行`try`块中的代码,如果发生异常,则捕获并处理该异常;无论是否有异常,`finally`块中的代码都会被执行。 - **异常处理中`throws`和`throw`的区别**...

    关于JAVA编程的书本总结

    - 每个可执行的Java程序至少需要一个主方法`public static void main(String[] args)`作为程序的入口点。 - 示例代码框架如下: ```java public class HelloWorld { public static void main(String[] args) { ...

    java期末复习题详解

    选项B(多线性)正确,意味着Java程序可以在不同的线程中同时执行多个任务。 2. 类声明:Java中,类的声明有特定规则。选项D(public abstract class Car{···})是正确的,因为它声明了一个公共抽象类Car。 3. ...

    Java essantial training(正常)翻译

    - 列举并解释Java中常用的关键字,如`public`, `private`, `static`, `final`等。 - **最佳实践**: - 推荐编码习惯,如避免硬编码、使用常量代替固定值等。 #### 四、控制流 - **条件判断**: - 使用if-else...

    Guess_java游戏_

    在Java编程领域,开发一款基于随机数的猜数字游戏是一个经典的练习项目,它能帮助初学者熟悉控制台输入输出...这个简单项目也可以作为进一步学习的基础,例如,添加更复杂的功能,如猜测次数限制、最佳猜测次数记录等。

Global site tag (gtag.js) - Google Analytics