基本的に私は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. scalaスレッドセーフHashSet
- 2. Java:What is - public static <T> foo(){...}?
- 3. JS public static pattern
- 4. 別の "public static function"で "public static function"の変数を使用
- 5. getterで 'public static final'または 'private static final'ですか?
- 6. Javaに関して<E> public static <E> void
- 7. public static Listからの追加データの取得List <>
- 8. public static classまたはconst
- 9. AjaxコールPHP Mysql public static function
- 10. のJavaのpublic static main()の
- 11. のpublic static変数値
- 12. public final static stringのテストクラス
- 13. apache tomcatサーブレット内のjava HashSetのスレッドセーフ
- 14. PHP | public/private関数の代わりにpublic static/private static関数を使うべきですか?
- 15. javaスレッドセーフ:スレッドセーフですか?
- 16. 動的にpublic staticを生成する
- 17. public static abstract classをjavaで作成できますか?
- 18. Javaインターフェイスの定数の「public static final」は冗長ですか?
- 19. public static void main(String [] [] args)を使用できますか?
- 20. プライベート文字列またはpublic static String?
- 21. Java - public static doubleが返されない
- 22. main()へのアクセスpublic static void main(String arg [])
- 23. ステージングサーバ上のPHPのstatic public classメンバ
- 24. シングルトンとのpublic static変数Javaの
- 25. System.setPropertyまたはpublic static変数?
- 26. Androidスタジオ2.0のアップデート - public static volatile com.android.tools.fd.runtime.IncrementalChange
- 27. 一般的な.NETクラスのpublic static(const)
- 28. boost_creative_ptr <XX>はスレッドセーフですか?
- 29. JedisSentinelPoolはスレッドセーフですか?
- 30. なぜpublic staticプロパティはオブジェクトを返しますか?
これは正しくはありません。 "静的フィールドの値がスレッドごとに一意であることを示します。"したがって、スレッド間でデータの共有はできません。すなわち3つのスレッド== 3つの静的インスタンス。 – sgtz
@sgtzが正しいです。 '[ThreadStatic]'はHashSetを魔法のようにスレッドセーフにしません。静的フィールドにアクセスするスレッドごとに異なる格納場所を表示します。 @Mike:あなた自身で 'HashSet'へのアクセスを同期させるか、' ConcurrentDictionary'のようなフリースレッドのコレクションを使う必要があります。 –
@sgtz:「スレッド間でデータの共有はできません」という意味はわかりません。 2つの場合ではありません。1.スレッドごとに1つの**インスタンス**がある場合、または** [ThreadStatic]で**静的**フィールドマークがある場合。私はあなたが間違っていると信じている部分を理解していません。 @Allon:OPは、1つのHashSetをスレッドセーフな「魔法のような」ものにしたくない場合、別のスレッドでアクセスされる3つの別々のHashSetが '[ThreadStatic]'でマークされる必要があるかどうか尋ねました。 HashSetがすべてのスレッドから同時にアクセス可能な静的フィールドでない限り、答えは** no **です(そうではありません)。 – Groo