zoukankan      html  css  js  c++  java
  • 静态初始化代码块启动新线程执行初始化

    package example;
    
     
    class Demo{
    static {  
        //创建匿名内部类来启动新线程
        Thread t = new Thread() {  
            public void run() {  
                System.out.println("进入run方法");  
                System.out.println("------" + website);  
                website = "www.leegang.org";  
                System.out.println("++++++" + website);  
                System.out.println("退出run方法");  
            }  
        };  
        t.start();  
        try {  
            //加入t线程
            t.join();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
    //定义一个静态field
    static String website = "www.crazyit.org";  
    
    public static void main(String args[]) {  
        System.out.println("main:" + Demo.website);  
    }  
    }

    奇怪的是只输出了进入run方法,并且在等待停止。

    分析:

    1,main线程试图访问Demo.website值,此时website尚未被初始化,因此main线程开始对该类执行初始化,步骤

        (1)为该类所有静态field分配内存

        (2)调用静态初始化块的代码执行初始化

    2,main线程为Demo类的website field分配内存空间,值为null

    3,main线程执行静态初始化块,创建一个新线程,并调用了join()方法,这说明main线程必须要等待新线程结束才能运行。

    4,新线程打印"进入run方法",并试图运行System.out.println("------" + website);这时用到了website,但website正在main线程中初始化,

    因为新线程会等待main线程对Demo类初始化结束。

    5.两个线程 相互等待,形成死锁

    下面去掉join()方法,查看结果

    package example;
    
     
    class Demo{
    static {  
        //创建匿名内部类来启动新线程
        Thread t = new Thread() {  
            public void run() {  
                System.out.println("进入run方法");  
                System.out.println("------" + website);  
                website = "www.leegang.org";  
                System.out.println("++++++" + website);  
                System.out.println("退出run方法");  
            }  
        };  
        t.start();  
        /*try {  
            //加入t线程
            t.join();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  */
    }  
    //定义一个静态field
    static String website = "www.crazyit.org";  
    
    public static void main(String args[]) {  
        System.out.println("main:" + Demo.website);  
    }  
    }

    main:www.crazyit.org
    进入run方法
    ------www.crazyit.org
    ++++++www.leegang.org
    退出run方法

    此时,main线程不会等待新线程结束,接着往下初始化,static String website = "www.crazyit.org"并打印,

    接着之后再去新线程代码。(调用一条线程的start方法后,该线程不会立即进入运行状态,只是保持在就绪状态)。

    在调用新线程时,让主线程暂停一下。

    package example;
    
     
    class Demo{
    static {  
        //创建匿名内部类来启动新线程
        Thread t = new Thread() {  
            public void run() {  
                System.out.println("进入run方法");  
                System.out.println("------" + website);  
                website = "www.leegang.org";  
                System.out.println("++++++" + website);  
                System.out.println("退出run方法");  
            }  
        };  
        t.start();  
        try {  
            
            Thread.sleep(1);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
    //定义一个静态field
    static String website = "www.crazyit.org";  
    
    public static void main(String args[]) {  
        System.out.println("main:" + Demo.website);  
    }  
    }

    进入run方法
    ------www.crazyit.org
    main:www.crazyit.org
    ++++++www.leegang.org
    退出run方法

    主线程暂停时,进行新线程执行代码,打印进入run方法之后, 执行System.out.println("------" + website);,

    但由于还没有初始化完成,所以会切换会main线程进行初始化website后,再去执行新线程。

    静态初始化启动的新线程赋值不是初始化操作,只是一次普通的赋直,如下代码编译失败。

    package example;
    
     
    class Demo{
        
    static {  
        //创建匿名内部类来启动新线程
        Thread t = new Thread() {  
            public void run() {  
            // website = "www.abc.org";  
            }  
        };  
        t.start();  
        try {  
            
            Thread.sleep(1);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
    
        //final static String website ;  编译失败
    
    public static void main(String args[]) {  
        
    }  
    }
  • 相关阅读:
    java工程师要求
    系统架构设计师知识模块
    Mybatis使用训练
    项目—视频直播系统
    [数算]概率
    查看镜像文件
    Hadoop启动命令
    Hadoop启动命令
    HDFS设置配额管理
    HDFS设置配额管理
  • 原文地址:https://www.cnblogs.com/xurui1995/p/5346541.html
Copyright © 2011-2022 走看看