`
liuInsect
  • 浏览: 132002 次
  • 性别: 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程序设计复习题.docx

    以下由 for 语句构成的循环执行的次数是( B )。 for ( int i = 0; true ; i++) ; Java程序设计复习题全文共7页,当前为第2页。 Java程序设计复习题全文共7页,当前为第2页。 A) 有语法错,不能执行 B) 无限次 C) ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler) 17 1.5.3 Java类库(Java Class Libraries) 17 1.5.4 Java虚拟机(Java Virtual ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler) 17 1.5.3 Java类库(Java Class Libraries) 17 1.5.4 Java虚拟机(Java Virtual ...

    Java面试宝典-经典

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    Java面试宝典2010版

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    java面试题大全(2012版)

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    达内 coreJava 习题答案

    i++){ //运行老久,减少循环次数会快很多,只是精确度小些 pi += (fenZi/fenMu) ; fenZi *= -1.0; //每项分子的变化是+4,-4,+4,-4 .... fenMu += 2.0; //分母的变化是1,3,5,7, .... 每项递加2 } ...

    java语言与面向对象程序设计作业题与参考答案汇编.doc

    答案:C 第10题 以下for循环的执行次数是()。 for(int x=0;(x==0)&(x>4);x++); A、无限次 B、一次也不执行 C、执行4次 D、执行3次 答案:B 多项选择题 第11题 如下哪些字串是Java中的标识符? A、fieldname B、...

    最新Java面试宝典pdf版

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    整理后java开发全套达内学习笔记(含练习)

    public static void main(String[] args){ System.out.println("请输入一列文字,包括空格:"); BufferedReader s = new BufferedReader(new InputStreamReader(System.in)); String next; try{next = s....

    java面试宝典2012

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 78 7、写一个Singleton出来。 81 8、递归算法题1 84 9、递归算法题2 85 10、排序都有哪几种方法?请列举。用JAVA...

    Java面试笔试资料大全

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    java 经典习题.doc

    (2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第一步。 (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。 【程序5】 题目:利用条件运算符的嵌套来完成此题...

    JAVA面试宝典2010

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    Java面试宝典2012新版

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用JAVA...

    跟我学Java面向对象程序设计技术及应用——识别某个自然数是否为质数(素数)的Java程序实现示例.doc

    (2)源程序截图 5、在MyEclipse开发工具中执行该示例程序 (1)启动"Run As"中的"Java Application"运行器以在Java虚拟机环境中执行示例 (2)在显示的控制台中输入数字13,将显示出判断的结果(程序判断正确) ...

    Java面试宝典2012版

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归算法题2 78 10、排序都有哪几种方法?请列举。用...

Global site tag (gtag.js) - Google Analytics