2017-10-14 18 views
0

Javaでsynchronized(){}を理解できません。どういうわけか、私はこのクラスのインスタンスをロックしていて、他のスレッドからこの特定のインスタンスの関数を呼び出す場合は、この他のスレッドが同期が終了するまで待つ必要があると思います。このサンプルコードでは何とかDOESNTが動作します。 スレッドBが何かをして後で続けるまで、スレッドAが待機するようにしたい。変数を同期/ロックする方法は?

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

同期が何をしているのかを間違っています。使用しているオブジェクトをロックしていませんが、そのオブジェクトをセマフォとして使用しています。あなたの例:

synchronized (this){ 
    loaded = true; 
} 

は、ワンライナー「loaded = true」をロックします。これは、別のスレッドが同じコード行を入力できないようにします。セマフォを解放することによって、(セマフォを所有する)最初のスレッドがブロックを離れるまで、 "synchronized(this)"ステートメントで待機します。

あなたの問題は、あるスレッドが他のスレッドのイベントを待って通知する方法が多いことです。それにはかなりの技術があります。現代のもの(java8)は、CompletableFutureを使用することです。 Javaのルーツであるもう1つは、wait()とnotify()のペアです。どちらも、各Object(およびそのderivetions)が知っているメソッドです。私が提供している後者の簡単な例this SO answer

+0

私は同期に関する3つの記事を読んだが、誰もその同じオブジェクトについてしか言及しなかった。非常にありがとう:) :)病気を待って見て今すぐ通知する。多分これは私の問題を解決するつもりです:) – ScriptWorld

関連する問題