黑马程序员技术交流社区

标题: 静态初始化块启动线程执行初始化时遇到的问题 [打印本页]

作者: 郑冬    时间: 2012-6-14 14:02
标题: 静态初始化块启动线程执行初始化时遇到的问题
本帖最后由 郑冬 于 2012-6-19 13:07 编辑

public class StaticThreadInit
{
         static
         {
                 Thread t = new Thread()
                 {
                         public void run()
                         {
                                 System.out.println("开始run方法");
                                 System.out.println(web);
                                 web = "www.123.com";
                                 System.out.println("停止run方法");
                         }
                 };
                 t.start();
                 try
                 {
                         t.join();
                 }
                 catch(Exception ex)
                 {
                         ex.printStackTrace();
                 }
                 
         }
         static String web = "www.123.com";
         public static void main(String [] args)
         {
                 System.out.println(StaticThreadInit.web);
         }
}
运行该程序,并没有直接输出www.123.com.只是输出了开始run方法,就不能继续向下执行,为什么?

作者: 张_涛    时间: 2012-6-14 14:19
首先对于这个问题,我们要了解类变量初始化和静态代码块初始化的顺序:
先静态代码块,再类变量
因此,在静态代码块初始化的时候,程序中使用了尚未初始化的类变量,因此需要等待类变量初始化之后才可继续。同时,类变量需要等静态代码快执行完毕后才可以进行初始化。所以,线程就陷入了不会结束的等待,从而只是输出了“开始run方法”。
作者: 张_涛    时间: 2012-6-14 14:19
首先对于这个问题,我们要了解类变量初始化和静态代码块初始化的顺序:
先静态代码块,再类变量
因此,在静态代码块初始化的时候,程序中使用了尚未初始化的类变量,因此需要等待类变量初始化之后才可继续。同时,类变量需要等静态代码快执行完毕后才可以进行初始化。所以,线程就陷入了不会结束的等待,从而只是输出了“开始run方法”。
作者: 胡卿    时间: 2012-6-14 14:22
  1. class StaticThreadInit
  2. {
  3.          static String web = "www.123.com";
  4.                  static
  5.          {
  6.                  Thread t = new Thread()
  7.                  {
  8.                          public void run()
  9.                          {
  10.                                  System.out.println("开始run方法");
  11.                                  System.out.println(web);
  12.                                  web = "www.123.com";
  13.                                  System.out.println("停止run方法");
  14.                          }
  15.                  };
  16.                  t.start();
  17.                  try
  18.                  {
  19.                          t.join(10);//join函数里面需等待程序终止的毫秒值
  20.                  }
  21.                  catch(Exception ex)
  22.                  {
  23.                          ex.printStackTrace();
  24.                  }
  25.                  
  26.          }
  27.          
  28.          public static void main(String [] args)
  29.          {
  30.                  System.out.println(StaticThreadInit.web);
  31.          }
  32. }
复制代码

作者: 胡卿    时间: 2012-6-14 14:23
本帖最后由 胡卿 于 2012-6-14 16:34 编辑

无法获取变量
class StaticThreadInit
{
         static String web = "www.123.com";
                 static
         {
                 Thread t = new Thread()
                 {
                         public void run()
                         {
                                 System.out.println("开始run方法");
                                 System.out.println(web);
                                 //web = "www.123.com";
                                 System.out.println("停止run方法");
                         }
                 };
                 
                 try
                 {
                         t.join();
      
                 }
                 catch(Exception ex)
                 {
                         ex.printStackTrace();
                 }
                  t.start();//start后开启就行了
         }
         
         public static void main(String [] args)
         {
                 System.out.println(StaticThreadInit.web);
         }
}
作者: 晏文根    时间: 2012-6-14 14:38
兄弟,这题真的很难。我做了些调试,但我没有发现其原因。
public class Test
{
          static
          {
  static String web = "www.123.com";
                  Thread t = new Thread()
                  {
                          public void run()
                          {
                                  System.out.println("开始run方法");
                                  System.out.println(1);//在运行中能输入1,所以就是下面这条语句出了问题。
                                  System.out.println(web);
                                  web = "www.123.com";
                                  System.out.println("停止run方法");
                          }
                  };
                  t.start();
                  try
                  {
                          t.join();
                  }
                  catch(Exception ex)
                  {
                          ex.printStackTrace();
                  }
                  
          }
          static String web = "www.123.com";
          public static void main(String [] args)
          {
                  System.out.println(Test.web);
          }
}
这里我是对其的修改,可以运行通过。
public class StaticThreadInit
{
          static
          {
                  final String web = "www.123.com";
                  Thread t = new Thread()
                  {
                          public void run()
                          {
                                  System.out.println("开始run方法");
                                  System.out.println(web);
                                  //web = "www.123.com";
                                  System.out.println("停止run方法");
                          }
                  };
                  t.start();
                  try
                  {
                          t.join();
                  }
                  catch(Exception ex)
                  {
                          ex.printStackTrace();
                  }
                  
          }
      
          public static void main(String [] args)
          {
                System.out。println(1);
          }
}

作者: 王章亚    时间: 2012-6-14 14:54
你这个程序的可阅读性太差了;
作者: 郑冬    时间: 2012-6-14 15:47
涅槃子衿 发表于 2012-6-14 14:19
首先对于这个问题,我们要了解类变量初始化和静态代码块初始化的顺序:
先静态代码块,再类变量
因此,在静 ...

程序执行输出了run方法之后是不是出现了死锁的情况?
作者: 张_涛    时间: 2012-6-14 15:58
郑冬 发表于 2012-6-14 15:47
程序执行输出了run方法之后是不是出现了死锁的情况?

应该可以这么认为的
static{}先执行,然后static web执行
但static{}中需要web变量
static web中需要static{}先执行完毕。
所以双方互相牵制导致不能进行下去。
作者: 胡卿    时间: 2012-6-14 16:03
oin:临时加入一个线程进行执行。
例如:
当主线程获取到了cpu的执行权,执行时,执行到了A线程的join方法。
这时就知道A线程要加入进来进行,那么A执行就需要cpu的执行权。
而这时cpu的执行权在主线程持有,主线程会释放自己的执行权。
让A线程进行执行。那么主线程什么时候执行呢?
只有等待A线程执行完以后,主线程才会执行,此时主线程就处于冻结状态。


一般使用情况,当在线程执行过程中,需要一个运算结束结果,可以通过加入一个临时线程,
将该结果进行运算,这时需要的结果的线程处于冻结状态,等加入的线程执行完,
该线程在继续执行。
作者: 郑冬    时间: 2012-6-14 16:22
涅槃子衿 发表于 2012-6-14 15:58
应该可以这么认为的
static{}先执行,然后static web执行
但static{}中需要web变量

产生这个的原因感觉应该是join()方法,可是注释掉这个方法为什么还是不行呢
作者: 张_涛    时间: 2012-6-14 16:24
郑冬 发表于 2012-6-14 16:22
产生这个的原因感觉应该是join()方法,可是注释掉这个方法为什么还是不行呢 ...

原因不是join()方法,你把静态代码块中有关没有初始化好的web全部去掉,你的程序就能奔完了。
我实验了的。
作者: 郑冬    时间: 2012-6-14 16:39
涅槃子衿 发表于 2012-6-14 16:24
原因不是join()方法,你把静态代码块中有关没有初始化好的web全部去掉,你的程序就能奔完了。
我实验了 ...

这个上边纠结了好久,才明白,非常感谢
作者: 张_涛    时间: 2012-6-14 17:02
郑冬 发表于 2012-6-14 16:39
这个上边纠结了好久,才明白,非常感谢

没事,互帮互助。
嘿嘿




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2