简体   繁体   English

OCJP 转储线程

[英]OCJP Dumps Thread

Can anyone help me to solve the following problem?谁能帮我解决以下问题?

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 A. 4

B. 5 B. 5

C. 8 C. 8

D. 9 D. 9

E. Compilation failure E、编译失败

F. An exception is thrown at runtime F. 运行时抛出异常

G. It is impossible to determine for certain G. 无法确定

In the dump the answer is D. I know that a new thread is created in new Starter().makeItSo.在转储中,答案是 D。我知道在 new Starter().makeItSo 中创建了一个新线程。 But can anyone tell me why the x*=2 in run() execute between x=x-1 and System.out.println(x) in method makeItSo?但是谁能告诉我为什么 run() 中的 x*=2 在 makeItSo 方法中的 x=x-1 和 System.out.println(x) 之间执行?

But can anyone tell me why the x*=2 in run() execute between x=x-1 and System.out.println(x) in method makeItSo但是谁能告诉我为什么 run() 中的 x*=2 在方法 makeItSo 中的 x=x-1 和 System.out.println(x) 之间执行

That's not what happens.这不是发生的事情。 Here's an explanation of what happens in the posted code:以下是对发布的代码中发生的事情的解释:

1) The main thread creates a new object of type Starter, initializing its instance variable x first to 2 (the variable initialization) and then (in the constructor) setting the same instance variable to 5, and starting the new thread. 1)主线程创建一个Starter类型的新对象,首先将其实例变量x初始化为2(变量初始化),然后(在构造函数中)将同一个实例变量设置为5,并启动新线程。

2) The main thread calls the method makeItSo (on the Starter instance created by the constructor call) and joins on the new thread, waiting until it finishes. 2) 主线程调用 makeItSo 方法(在构造函数调用创建的 Starter 实例上)并加入新线程,等待它完成。

3) The new thread executes its run method, doubling x, and finishes (notifying the main thread that it's done). 3)新线程执行其run方法,将x加倍,并完成(通知主线程它已完成)。

4) The main thread then wakes up, subtracts 1 from x, and prints 9. 4) 然后主线程唤醒,x 减 1,打印 9。

Since x is modified across threads and isn't volatile or atomic and no synchronization is performed, it's not obvious that the updates to x by the new thread are guaranteed to be made visible to the main thread (so whether it works on purpose or by accident is unclear), making G look like the right answer.由于 x 是跨线程修改的,并且不是易失性或原子性的,并且不执行同步,因此新线程对 x 的更新是否保证对主线程可见并不明显(因此无论它是故意工作还是通过事故不清楚),使 G 看起来像正确的答案。 But join does synchronization on the new thread (since join is implemented using wait, locking on the thread);但是join在新线程上做同步(因为join是使用wait实现的,锁定线程); the current value of x will be visible by the time the main thread returns from the join call. x 的当前值将在主线程从 join 调用返回时可见。 So the answer is D.所以答案是D。

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

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