2016-01-02 9 views
6

私はこれに類似しているクラスがあります。メソッドは、ロックが解放されるのをどのように待っていますか?

public class ExpensiveCalculation { 
    private Executor threadExecutor = ... 
    private Object lock = new Object(); 

    private Object data = null; 

    public Object getData() { 
    synchronized(lock) { 
     return data; 
    } 
    } 

    pulic void calculate() { 
    executor.execute(() -> internalCalculation()); 
    } 
    private void internalCalculation() { 
    synchronized(lock) { 
     // do some long running calculation that in the end updates data 
     data = new Object(); 
    } 
    } 
} 

このクラスは、いくつかの高価な(時間的)な計算を行い、ロックを取得します。ロックが保持されている間は、誰も計算によって更新されるデータを取得することはできません。そのため、計算を完了するまで待つ必要があります。実際の計算は別のスレッドで行われます。私は次のコードをお持ちの場合 は:

ExpensiveCalculation calculation = ... 
calculation.calculate(); 
Object data = calculation.getData(); 

を計算が完了するまでのデータを取得するための呼び出しはブロックされています。この時点で待っているのはどういう意味ですか?

  • は忙しい待機中のスレッドの収率は
  • ん待って、(計算を行うような)ので、他のスレッドが進むことができ、それです。
  • 待ちスレッドがスリープ状態になるかどうかを確認します。
  • シーンの後ろに待機/通知が呼び出されていますか?

私は、この例のために、私はCallableFutureを使用することができることを承知していますが、それはポイントの横にあります。そのようなコードを改善する方法はありますか?(不必要なスレッドスイッチのように)時間の無駄なリソースが無駄にならないようにする方法はありますか?

+0

呼び出した場合はたぶん、[この](http://stackoverflow.com/questions/6584355/how-does-the-synchronize-functionnality-work-in-javaは) – MadProgrammer

答えて

2

それは

を待って待機中のスレッドの歩留まりをんので、(計算を行うような)他のスレッドを進めることができます忙しいです。

いいえ、ブロックするので、他のスレッドを実行できます。

待機スレッドがスリープ状態になるかどうかを確認します。

ブロックされています。

シーンの後ろに待機/通知が呼び出されていますか?

+0

を助けるかもしれませんスレッドの利回りに応じて、定期的にロックを試行して取得できるスロットを取得します。これは、計算からの 'ロック'の解放とデータを取り出すための 'ロック 'の再取得との間にある程度の時間が経過する可能性があることを意味する。あれは正しいですか? – hotzst

+0

実際には、ある種の 'wait/notify'メカニズムが使われていますが、これはOSの機能を使った低レベルのメカニズムです。あらかじめ定義されたセットからのイベントが発生するまで、ウェイタースレッドはブロックされます。解放ロック(他のスレッド)はそのようなイベントの1つであり、このイベントが発生した後、ウェイター・スレッドはすぐにスケジューリングのためにアクセスされます。 – Tsyvarev

関連する問題