繁体   English   中英

OCJP 转储线程

[英]OCJP Dumps Thread

谁能帮我解决以下问题?

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;}
}

A. 4

B. 5

C. 8

D. 9

E、编译失败

F. 运行时抛出异常

G. 无法确定

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

但是谁能告诉我为什么 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 的当前值将在主线程从 join 调用返回时可见。 所以答案是D。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM