2015-10-20 88 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.