2017-01-26 8 views
0

私は、この特定の例に来たところ、私は現在、およそIntrinsic Locks and Synchronization oracle.com上を読んでいます:組み込みロックと同期

同期文はまた、きめ細かい同期と並行性を改善するのに有用です。たとえば、クラスMsLunchに2つのインスタンスフィールド、c1c2があり、それらは決して一緒に使用されないとします。これらのフィールドの更新はすべて同期する必要がありますが、c1の更新がc2の更新でインターリーブされるのを防ぐ理由はありません。そうすることで、不要なブロックを作成することで並行性が低下します。代わりにsynchronizedメソッドを使用して、あるいはこれに関連したロックを使用しての、我々は単にロックを提供するために、2つのオブジェクトを作成します。このセクションの前に

public class MsLunch { 
    private long c1 = 0; 
    private long c2 = 0; 
    private Object lock1 = new Object(); 
    private Object lock2 = new Object(); 

    public void inc1() { 
     synchronized(lock1) { 
      c1++; 
     } 
    } 

    public void inc2() { 
     synchronized(lock2) { 
      c2++; 
     } 
    } 
} 

、説明​​方法:あるべき

public synchronized void increment() { 
    this.c++; 
} 

を、そして私が間違っている場合であれば

public void increment() { 
    synchronized(this) { 
     c++; 
    } 
} 

と同じ、私を修正してください私はincrement()に機能性を追加していませんが、それは正しいのですか?

私の質問は、今のフレーズから来ている:私ならば、私はわからないc2

の更新にをインターリーブ

しかしであることからc1の更新を防止するための理由はありません"interleaved"とはこの文脈での意味を完全に理解する。たとえば、もし私がMsLunch例からlock2を削除します。私はロックとトラブルに巻き込まれる可能性が

public class MsLunch { 
    private long c1 = 0; 
    private long c2 = 0; 
    private Object lock1 = new Object(); 
    // private Object lock2 = new Object(); // 'lock2' is no more! 

    public void inc1() { 
     synchronized(lock1) { 
      c1++; 
     } 
    } 

    public void inc2() { 
     synchronized(lock1) { // Using 'lock1' here too 
      c2++; 
     } 
    } 
} 

inc1()thread-1ランは、lock1からロックを取得しますが、インクリメントまたはロックを解除できるようになる前に中断しますと言います。今度はthread-2がと入力され、別のロックがlock1に対して作成されます。これは別のlock2を使用することによって回避し、これは私がロックプロバイダとして単にthisを使用していないだろう理由ですされているものですか?言い換えれば、これは問題を引き起こす可能性がありますか?ここ

+0

いいえ、* trouble *に入ることはできません。同じロックを共有しているので、 'c1'と' c2'が同時に増加するのを不必要に防ぎます分離された 'lock1')、ロックを介してそれらの間に依存関係があります。 – Kayaman

+0

@Kayamanああ、 "interleaved"のドイツ語翻訳は、 "お互いに"、 "お互いに"のようなものなので、ちょっと混乱します。しかし、なぜこれが同時に 'c1'と' c2'を防ぐのですか? 'lock1'のみの例では、' lock1'がコード内のロック「* anywhere *」を保持している場合、それは他の場所でブロックされることを意味しますか?したがって、 'thread-2'は' thread-1'が 'c1'を更新してから' c2'を更新するのを待たなければなりません。これはまた、各オブジェクトが同時に* 1つの*ロックしか提供できないことを意味します。 – displayname

+0

はい、各オブジェクトは一度に1つのロックを提供します。それが、同期がなぜそれと同じように機能するのかという全体的な考えです。 – Kayaman

答えて

2

2つのロックだけで独立してc1c2を高め、ロックが解除されたときに待機しない可能性を持っています。したがってThread-1c1の同期ブロックに入り、lock1を取得した場合、別のThread-2thread-1がロックを解除するのを待たずにc2を増やすことができます。注意することは重要


MsLunchのインスタンスの参照はMsLunchの外部表示されているので、共有モニタとしてthisのUSING

は独自の問題を有しています。例えば。Thread-3はこのクラス外のsynchronized (msLunchInstance)のロックを取得できます。

+0

ありがとう! 「this」に関する説明は+1です。私はこの含意については考えていませんでした。もし、この権利を得るなら、 'this'を使うことでパフォーマンス上の問題を本当に隠すことができます。 :D – displayname

関連する問題