基本的に私は3つの異なるスレッドを呼び出すアプリケーションを持っていますが、それぞれ新しいHashSetと私が知りたいのはこのスレッドセーフですか?または各ハッシュセットに[ThreadStatic]を追加する必要がありますか?public static HashSet <string>スレッドセーフですか?
4
A
答えて
6
3つの異なるHashSet
をインスタンス化し、それぞれのHashSet
にアクセスする場合は、1つのスレッドでしかアクセスできません。スレッド内で共有される1つのスタティックHashSet
がある場合は、[ThreadStatic]
属性を追加する必要があります。
[更新][ThreadStatic]
がどのように機能するかを明確にするだけです。
免責事項:I 決してを使用[ThreadStatic]
。その属性の存在は明白ではなく、(適切にテストするだけでなく)デバッグするのが難しい多くの結果をもたらします。
のは、あなたが本当にテストクラスで[ThreadStatic]
を使用したいとしましょう:次のコンソールアプリ実行
public class ThreadStaticTest
{
// CLR ensures that each thread accessing this field
// gets a separate instance of the *field*. This, however,
// means that static initializers don't work. Field is
// null at first access from an individual thread
[ThreadStatic]
static HashSet<string> _hashset;
// This is why we instantiate it explicitly here:
private HashSet<string> HashSet
{
get
{
_hashset = _hashset ?? new HashSet<string>();
return _hashset;
}
}
public void AddItem(string s)
{
// thread safe
HashSet.Add(s);
}
public IEnumerable<string> GetItems()
{
// thread safe
return HashSet;
}
}
:
static void Main(string[] args)
{
// single test instance!
var test = new ThreadStaticTest();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 5; i++)
{
threads.Add(new Thread(() =>
{
var threadId = Thread.CurrentThread.ManagedThreadId;
test.AddItem("Hello from thread #" + threadId);
Console.WriteLine("Instance contains {0} items: '{1}'",
test.GetItems().Count(),
string.Join(", ", test.GetItems().ToArray()));
}));
}
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
Console.Read();
}
は、各スレッド、単一のテストインスタンスがあるが、ことを示しますハッシュセットの新しいインスタンスを取得します。
Instance contains 1 items: 'Hello from thread #11' Instance contains 1 items: 'Hello from thread #13' Instance contains 1 items: 'Hello from thread #10' Instance contains 1 items: 'Hello from thread #12' Instance contains 1 items: 'Hello from thread #14'
4
MSDNドキュメントHashSet
:
この型のパブリックstatic(Visual BasicではShared)のメンバーはすべて、スレッドセーフです。どのインスタンスメンバーもスレッドセーフであるとは限りません。
関連する問題
- 1. Java:What is - public static <T> foo(){...}?
- 2. JS public static pattern
- 3. getterで 'public static final'または 'private static final'ですか?
- 4. Javaに関して<E> public static <E> void
- 5. のJavaのpublic static main()の
- 6. のpublic static変数値
- 7. public final static stringのテストクラス
- 8. apache tomcatサーブレット内のjava HashSetのスレッドセーフ
- 9. PHP | public/private関数の代わりにpublic static/private static関数を使うべきですか?
- 10. 動的にpublic staticを生成する
- 11. public static abstract classをjavaで作成できますか?
- 12. プライベート文字列またはpublic static String?
- 13. ステージングサーバ上のPHPのstatic public classメンバ
- 14. シングルトンとのpublic static変数Javaの
- 15. Androidスタジオ2.0のアップデート - public static volatile com.android.tools.fd.runtime.IncrementalChange
- 16. 一般的な.NETクラスのpublic static(const)
- 17. Javaインターフェイスの定数の「public static final」は冗長ですか?
- 18. public static void main(String [] [] args)を使用できますか?
- 19. boost_creative_ptr <XX>はスレッドセーフですか?
- 20. ASP.NET public staticメソッドからclientscriptを呼び出す方法
- 21. C++でpublic static変数を宣言するときのリンクエラー
- 22. "public static final int"値を名前で取得するには?
- 23. HashSetでDistinct <>()を呼び出す
- 24. public static voidは何を意味しますか?クラスとは何ですか?
- 25. final public static intsはswitch文で使用できません。
- 26. public static void main(string args [])でstaticを使用しない方法はありますか?
- 27. .NET 4 ISet <> HashSet <>はNHibernate Iesi.Collections ISet、HashSetを置き換えることができますか?
- 28. SortedSet <T> vs HashSet <T>
- 29. C#HashSetの<T>読み取り専用の回避策
- 30. HashSetの<T> .RemoveWhere()とGetHashCodeメソッド()
これは正しくはありません。 "静的フィールドの値がスレッドごとに一意であることを示します。"したがって、スレッド間でデータの共有はできません。すなわち3つのスレッド== 3つの静的インスタンス。 – sgtz
@sgtzが正しいです。 '[ThreadStatic]'はHashSetを魔法のようにスレッドセーフにしません。静的フィールドにアクセスするスレッドごとに異なる格納場所を表示します。 @Mike:あなた自身で 'HashSet'へのアクセスを同期させるか、' ConcurrentDictionary'のようなフリースレッドのコレクションを使う必要があります。 –
@sgtz:「スレッド間でデータの共有はできません」という意味はわかりません。 2つの場合ではありません。1.スレッドごとに1つの**インスタンス**がある場合、または** [ThreadStatic]で**静的**フィールドマークがある場合。私はあなたが間違っていると信じている部分を理解していません。 @Allon:OPは、1つのHashSetをスレッドセーフな「魔法のような」ものにしたくない場合、別のスレッドでアクセスされる3つの別々のHashSetが '[ThreadStatic]'でマークされる必要があるかどうか尋ねました。 HashSetがすべてのスレッドから同時にアクセス可能な静的フィールドでない限り、答えは** no **です(そうではありません)。 – Groo