私は、この特定の例に来たところ、私は現在、およそIntrinsic Locks and Synchronization oracle.com上を読んでいます:組み込みロックと同期
同期文はまた、きめ細かい同期と並行性を改善するのに有用です。たとえば、クラスMsLunchに2つのインスタンスフィールド、
c1
とc2
があり、それらは決して一緒に使用されないとします。これらのフィールドの更新はすべて同期する必要がありますが、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
を使用していないだろう理由ですされているものですか?言い換えれば、これは問題を引き起こす可能性がありますか?ここ
いいえ、* trouble *に入ることはできません。同じロックを共有しているので、 'c1'と' c2'が同時に増加するのを不必要に防ぎます分離された 'lock1')、ロックを介してそれらの間に依存関係があります。 – Kayaman
@Kayamanああ、 "interleaved"のドイツ語翻訳は、 "お互いに"、 "お互いに"のようなものなので、ちょっと混乱します。しかし、なぜこれが同時に 'c1'と' c2'を防ぐのですか? 'lock1'のみの例では、' lock1'がコード内のロック「* anywhere *」を保持している場合、それは他の場所でブロックされることを意味しますか?したがって、 'thread-2'は' thread-1'が 'c1'を更新してから' c2'を更新するのを待たなければなりません。これはまた、各オブジェクトが同時に* 1つの*ロックしか提供できないことを意味します。 – displayname
はい、各オブジェクトは一度に1つのロックを提供します。それが、同期がなぜそれと同じように機能するのかという全体的な考えです。 – Kayaman