2

それで、ロックの問題を抱えていた何かに取り組んでいるときに、ある質問が私に来ました。単一のスレッドからのみアクセスできるオブジェクトには、ロックまたは同期がまったく必要ですか?

たとえば、Thread1、Thread2、および Thread3 が、Buffer1、Buffer2、Buffer3 とともに、スレッドが作成されるときに各バッファーがインスタンス化されている場合、Thread1 は Buffer1 にのみアクセスし、Thread2 および Buffer2 と Thread3 についても同様です。およびBuffer3。Thread1 が Buffer2 または Buffer3 にアクセスすることはありません。ストリーム内のバイトを追加/削除/変更している間、ロックは必要ですか?

4

6 に答える 6

2

いいえ、この場合、ロックは必要ありません。ロックと同期は、リソースが複数のスレッド間で共有されている場合にのみ必要です。

先に進んでそのバッファのプライベート インスタンスに同期を追加しても、ロックの取得を待機しているスレッドがないため、違いはありません。バッファをロックおよび解放するのは所有者スレッドだけです。

于 2012-07-31T04:11:59.627 に答える
1

いいえ。スレッドセーフを確保するためのこの戦略は、一般に閉じ込めと呼ばれます。

閉じ込めは、複数のスレッドがオブジェクトにアクセスできないようにするためのカプセル化手法に依存しています。DougLeaによる「ConcurrentProgramminginJava」には、他の除外手法と比較した、閉じ込めの詳細とその長所と短所に関する優れた章があります。

Leaから言い換えると、一般に、メソッドm内で参照rをオブジェクトxに閉じ込めるのに必要な条件は4つあります。

  1. mはrを引数として別のメソッドに渡すことはできません。
  2. mはrを戻り値として渡すことはできません。
  3. mは、別のスレッドからアクセス可能なフィールド(インスタンスまたは静的)にrを記録できません。
  4. mは、rにトラバースされる可能性のある他の参照を(1〜3を介して)エスケープさせることはできません。
于 2012-07-31T04:06:45.357 に答える
1

1.複数のスレッドがオブジェクトにアクセスしようとすると、ロックが必要になります

2.さらに、スレッドによる同時アクセスが可能な場合、開発時のクラスはスレッドセーフである必要があります。

3.クラスは、クライアントからの同期メカニズムなしで、基盤となる OS のインターリーブとスケジューリングが存在する場合に正しく動作する場合、スレッドセーフであると言われます。

4. リソースをロックすると、オーバーヘッドが発生し、同時アクセスが妨げられ、ボトルネックが発生する可能性があります。

于 2012-07-31T04:27:51.613 に答える
1

2 つ以上のスレッドが共有オブジェクトにアクセスする必要がある場合にのみ、ロックについて心配する必要があります。

于 2012-07-31T04:02:57.720 に答える
0

スレッドが同じデータ構造を同時に使用していない限り、ロックは必要ありません。

したがって、スレッドごとに異なるデータ構造が使用されている場合、コードはスレッドセーフであることが保証されます。

java.util.ArrayListちなみに、これが次のような主要なJavaコレクションクラスがスレッドセーフではない主な理由の1つです。スレッドセーフにすると、パフォーマンスオーバーヘッドが追加され、必要がない場合は料金を支払う必要がなくなります。一度に1つのスレッドだけがArrayListにアクセスすることを他の方法で保証できるため、必要ない場合もあります。

于 2012-07-31T04:08:41.593 に答える
0

私の研究から覚えていることから、すべてのスレッドにプライベート バッファを使用している場合、同時アクセスを避けるためにロックすることを心配する必要はありません。

作成者以外に誰もバッファを読んでいない場合、他の誰かがバッファを読み書きしていることを心配することなく、作成者がやりたいことを何でも行うことができます。だからあなたは大丈夫なはずです

ただし、スレッドはいつでも中断される可能性があるため、内部バッファーが一貫性のない状態になる可能性があることを覚えておく必要があります。(同じスレッドからシーケンシャルにしかアクセスしていないため、これは問題になりません)

于 2012-07-31T04:06:19.343 に答える