2015-10-20 28 views
-2

任何人都可以帮助我解决以下问题吗?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.我知道一个新的线程是在新的Starter()。makeItSo中创建的。但任何人都可以告诉我为什么run()中的x * = 2在方法makeItSo中的x = x-1和System.out.println(x)之间执行?

+0

什么是答案D?你为什么认为任何东西之间执行任何事情? –

回答

1

但谁能告诉我,为什么X * = 2的run()X = X-1和的System.out.println(X)在方法makeItSo

这不会发生什么变化之间执行。下面是对发布代码中发生的事情的解释:

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

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

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

4)然后,将主线程被唤醒时,从X减去1,并打印9.

由于x是跨线程修改并且是不挥发的或原子,并且不执行同步,这不是显而易见的是通过新线程对x的更新保证可以让主线程看到(所以不管是故意还是意外都不清楚),使G看起来像是正确的答案。但是join在新线程上进行同步(因为join是使用wait,锁定线程来实现的);当主线程从加入调用返回时,x的当前值将可见。所以答案是D.