2017-10-14 141 views
0

我有一個理解Java中synchronized(){}的問題。不知何故,我認爲同步(this)我鎖定了這個類的實例,如果我想訪問一個屬性或從另一個線程調用這個特定實例的函數,比這個其他線程必須等待,直到同步結束。在這個示例代碼中,它不工作。 我希望線程A等待線程B做些什麼,然後再繼續。如何同步/鎖定一個變量的權利?

public class A implements Runnable{ 
public void start(){ 
    Thread t = new Thread(this); 
    t.start(); 
} 
public void run(){ 
    B b = new B(); 
    b.start(); 

    //DO STUFF 
    while(b.loaded){ 
     //WAIT FOR B DOING STUFF 
    } 

    //GO ON DOING STUFF 
} 
} 

public class B implements Runnable { 
public boolean loaded; 
public B(){ 
    loaded = false; 
} 
public void start(){ 
    Thread thread = new Thread(this); 
    thread.start(); 
} 

public void run(){ 
    //DOING STUFF 
    synchronized (this){ 
     loaded = true; 
    } 
    //DO OTHER STUFF 
} 

} 

,如果我做一個調用的方法它的工作原理,

public synchronized boolean getLoaded(){return loaded;} 

但爲什麼寫作和閱讀過程必須同步?如果在寫入原因時只鎖定了對象,那麼閱讀是否必須等待呢?在第一個例子中,我所期望的編程做以下的東西:

線程A正在讀取加載變量。

線程B想要寫入加載的變量,但其同步,所以它鎖定對象。

線程A試圖讀取加載可變的,但該對象被鎖定,從而它等待。

線程B寫入變量。

線程B解鎖。

線程A繼續閱讀。

我讀了很多關於這個主題,但我無法理解它像100%。希望有人能向我解釋那個簡單的項目。

回答

1

你有什麼不同步,這不是鎖定您使用該對象的錯誤認識,但它使用對象作爲一個信號鎖定一塊exeutable代碼。你的榜樣:

synchronized (this){ 
    loaded = true; 
} 

只鎖定一個襯裏「加載=真」。它可以防止另一個線程可以輸入相同的代碼行。它在「同步(本)」語句中等待,直到第一個線程(擁有信號量)離開該塊,釋放信號量。

你的問題是一個多線程如何等待,大約在其他線程的事件通知。有很多不同的技術可以做到這一點。現代的(java8)是使用CompletableFuture。另一個,更在java的根源是wait()和notify(),它們都是每個對象(及其派生)所知道的方法。我已經提供了後者在this SO answer

+0

一個簡單的例子,我讀3篇有關同步,但沒有一個人提到,其只對同一個對象..容易解釋,但最後我明白做什麼同步!非常感謝:))現在請看看現在等待通知。也許這是要解決我的問題:) – ScriptWorld