A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 郑冬 于 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方法,就不能继续向下执行,为什么?

13 个回复

倒序浏览
首先对于这个问题,我们要了解类变量初始化和静态代码块初始化的顺序:
先静态代码块,再类变量
因此,在静态代码块初始化的时候,程序中使用了尚未初始化的类变量,因此需要等待类变量初始化之后才可继续。同时,类变量需要等静态代码快执行完毕后才可以进行初始化。所以,线程就陷入了不会结束的等待,从而只是输出了“开始run方法”。

评分

参与人数 2技术分 +1 黑马币 +1 收起 理由
李海 + 1 赞一个!
职业规划-刘倩老师 + 1

查看全部评分

回复 使用道具 举报
首先对于这个问题,我们要了解类变量初始化和静态代码块初始化的顺序:
先静态代码块,再类变量
因此,在静态代码块初始化的时候,程序中使用了尚未初始化的类变量,因此需要等待类变量初始化之后才可继续。同时,类变量需要等静态代码快执行完毕后才可以进行初始化。所以,线程就陷入了不会结束的等待,从而只是输出了“开始run方法”。
回复 使用道具 举报
  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 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);
         }
}
回复 使用道具 举报
兄弟,这题真的很难。我做了些调试,但我没有发现其原因。
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 15:47:04
8#
涅槃子衿 发表于 2012-6-14 14:19
首先对于这个问题,我们要了解类变量初始化和静态代码块初始化的顺序:
先静态代码块,再类变量
因此,在静 ...

程序执行输出了run方法之后是不是出现了死锁的情况?
回复 使用道具 举报
张_涛 黑马帝 2012-6-14 15:58:48
9#
郑冬 发表于 2012-6-14 15:47
程序执行输出了run方法之后是不是出现了死锁的情况?

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


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

产生这个的原因感觉应该是join()方法,可是注释掉这个方法为什么还是不行呢
回复 使用道具 举报
张_涛 黑马帝 2012-6-14 16:24:30
12#
郑冬 发表于 2012-6-14 16:22
产生这个的原因感觉应该是join()方法,可是注释掉这个方法为什么还是不行呢 ...

原因不是join()方法,你把静态代码块中有关没有初始化好的web全部去掉,你的程序就能奔完了。
我实验了的。
回复 使用道具 举报
涅槃子衿 发表于 2012-6-14 16:24
原因不是join()方法,你把静态代码块中有关没有初始化好的web全部去掉,你的程序就能奔完了。
我实验了 ...

这个上边纠结了好久,才明白,非常感谢
回复 使用道具 举报
张_涛 黑马帝 2012-6-14 17:02:33
14#
郑冬 发表于 2012-6-14 16:39
这个上边纠结了好久,才明白,非常感谢

没事,互帮互助。
嘿嘿
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马