webdevqa.jp.net

List <T>がスレッドセーフではないのはなぜですか?

次のサイトから:

http://crfdesign.net/programming/top-10-differences-between-Java-and-c

残念ながら、List<>はスレッドセーフではありません(C#のArrayListおよびJavaのVectorはスレッドセーフです)。 C#にもHashtableがあります。一般的なバージョンは次のとおりです。

何がList<T>スレッドセーフではありませんか? .NETフレームワークエンジニア側の実装問題ですか?またはジェネリックはスレッドセーフではありませんか?

42
Hao

あなたは本当にJavaのVectorのタイプのスレッドセーフティを分類する必要があります。 Javas Vectorはメソッドで同期を使用するため、複数のスレッドから使​​用しても安全です。状態は破損しません。

ただし、Javaのベクターの有用性は、追加の同期を行わない複数のスレッドから制限されます。たとえば、ベクトルから要素を読み取るという単純な行為を考えてみましょう。

Vector vector = getVector();
if ( vector.size() > 0 ) { 
  object first = vector.get(0);
}

このメソッドはベクターの状態を壊しませんが、それも正しくありません。 ifステートメントとget()呼び出しの間で、別のスレッドがベクターを変更するのを妨げるものはありません。このコードは、競合状態のため、最終的にwillに失敗する可能性があります。

このタイプの同期は、少数のシナリオでのみ有用であり、決して安くはありません。複数のスレッドを使用していなくても、同期には目立つ価格を支払います。

.Netは、有用性が限られているシナリオでは、デフォルトでこの価格を支払わないことを選択しました。代わりに、ロックのないリストを実装することを選択しました。作成者は、同期を追加する必要があります。 C++の「使用した分だけ支払う」モデルに近い

私は最近、Javaのベクターなどの内部同期のみでコレクションを使用することの危険性に関するいくつかの記事を書きました。

参照ベクターのスレッドセーフティ: http://www.ibm.com/developerworks/Java/library/j-jtp09263.html

67
JaredPar

なぜするスレッドセーフなのですか?すべてのクラスがそうであるとは限りません。実際、デフォルトでは、クラスはnotスレッドセーフです。

スレッドセーフであることは、リストを変更するすべての操作を同時アクセスに対してインターロックする必要があることを意味します。これは、単一のスレッドでのみ使用されるリストでも必要です。それは非常に非効率的です。

20
John Saunders

スレッドセーフではない型を実装することは、単に設計上の決定です。コレクションは、データタイプを明示的に同期するために、一部のコレクションでインターフェイスSyncRootのプロパティICollectionおよびSynchronized()メソッドを提供します。

マルチスレッド環境でオブジェクトをロックするには、SyncRootを使用します。

_lock (collection.SyncRoot)
{
   DoSomething(collection);
}
_

コレクションのスレッドセーフなラッパーを取得するには、collection.Synchronized()を使用します。

9

JaredParが言及している競合状態の可能性は、Vectorの想定されたスレッドセーフに依存することの恐ろしい結果です。これは、「9日ごとの火曜日にアプリが奇妙なことをする」という種類の欠陥レポートのようなもので、あなたを狂わせます。

本当にスレッドセーフなコレクション 。Net 4で提供される がいくつかあり、シングルスレッドで実行できるという興味深い副作用があります 列挙中のコレクションの変更パフォーマンスヒット があり、スレッドセーフが付属している場合があります。

したがって、フレームワーク開発者が行うべき論理的なことは、おそらくスレッド化を行わないユーザーの95%が可能な限りクラスのパフォーマンスを維持し、マルチスレッドを実行するユーザーに、維持するために何をすべきかを知ってもらうことです。安全です。

2
Ragoczy

真のスレッドセーフのために、List<>およびその他のコレクション型は不変である必要があります。 .NET 4.0で提供される.NETの並列拡張により、最も一般的に使用されるコレクションのスレッドセーフバージョンが表示されます。 Jon Skeet これのいくつかに触れます。

2
Abhijeet Patel

synchronizedCollectionを使用すると、共有同期を使用するためのConstructor-Parameterも提供されます:)

0
mo.