OCJP转储线程

时间:2015-10-20 01:14:57

标签: java multithreading scjp java-threads

有谁能帮我解决以下问题?

public class Starter extends Thread{
   private int x=2;
   public static void main(String[] args) throws Exception{
      new Starter().makeItSo();
   }
   public Starter(){
      x=5;
      start(); 
   }
   public void makeItSo() throws Exception {
      join();
      x=x-1;
      System.out.println(x);
   }
   public void run(){x*=2;}
}

一个。 4

B中。 5

℃。 8

d。 9

电子。编译失败

F。在运行时抛出异常

-G。确定某些

是不可能的

在转储中答案是D.我知道在新的Starter()。makeItSo中创建了一个新线程。但有人能告诉我为什么run()中的x * = 2在方法makeItSo中的x = x-1和System.out.println(x)之间执行?

1 个答案:

答案 0 :(得分:1)

  

但是有人能告诉我为什么run()中的x * = 2在方法makeItSo

中的x = x-1和System.out.println(x)之间执行

那不是发生了什么。以下是对发布的代码中发生的事情的解释:

1)主线程创建一个Starter类型的新对象,首先将其实例变量x初始化为2(变量初始化),然后(在构造函数中)将相同的实例变量设置为5,然后启动新线程。

2)主线程调用方法makeItSo(在构造函数调用创建的Starter实例上)并加入新线程,等待它完成。

3)新线程执行其run方法,将x加倍,并完成(通知主线程它已完成)。

4)然后主线程被唤醒,从x中减去1,然后打印9。

由于x是跨线程修改的,并且不是易失性的或原子的,并且没有执行同步,因此新线程对x的更新保证对主线程可见是不明显的(因此,无论是故意还是偶然工作都不清楚),使G看起来像是正确的答案。但是join在新线程上执行同步(因为join是使用wait实现的,在线程上锁定);当主线程从连接调用返回时,x的当前值将可见。所以答案是D。