3

100 アイテムのリストと、お互いのアイテムを変更しないようにそれぞれ 25 アイテムを変更する 4 つのスレッドがある場合、リストは「スレッドセーフ」になります。期待どおりに動作しますか?

たとえば、1000 匹の猫の配列があり、名前が付けられていないため、'name' プロパティが空白になっているとします。すべてを調べて名前を付けたいが、マルチスレッドにしたい。したがって、10 個のスレッドを作成し、それぞれに 0 ~ 99、100 ~ 199 などのみを実行するように指示し、それらを開始します。

4

4 に答える 4

2

他の人がすでに指摘しているように、読み取りの行為は本質的にスレッドセーフです。同時実行性が問題になるのは、特定のスレッドが書き込みたい場合や、他のスレッドがリソースから読み取りたい場合のみです。

そうは言っても、この目的でコレクションを使用する場合は、明示的な読み取り専用コレクションの使用 (または単に IEnumerable の使用) を検討できることを付け加えておきます。.NET は、これらの読み取り専用コレクションをすぐに使用できるようになりました。これにより、コレクションからのみ読み取っていることがより明確になります。

余談ですが、要件のコンテキストがわかりません。おそらくここで問題を単純化しすぎたのかもしれませんが、メモリ内コレクションへのシリアルアクセスは非常に高速であるため、コレクションから複数のスレッドを読み取るだけです次の場合に十分に根拠があります。

  • メモリからではなくディスクから読み込んでいます (I/O が遅い)
  • オブジェクトを操作するために実行しているアクションが遅い (単純なプロパティの変更ではなく、ミリ秒以上のオーダーで)
于 2013-07-17T11:18:35.443 に答える
2

リストから読み取るだけなので、これは機能します。あなたはそれに書きません。

于 2013-07-17T10:52:14.323 に答える
1

リスト自体を変更 (アイテムの追加または削除) しておらず、4 つのスレッドが独自のオブジェクトでのみ動作することを保証できる場合は、スレッド同期の観点からは問題ありません。

于 2013-07-17T10:54:47.157 に答える
0

いくつかの自作スレッドの代わりに、並列 linq 機能を使用できます。

namespace CSharp
{
  using System;
  using System.Collections.Generic;
  using System.Linq;

  class Cat
  {
    public string Name { get; set; }
  }

  class Program
  {
    private static void Main()
    {
      var cats = new List<Cat>();

      for (int i = 0; i < 100; ++i)
      {
        cats.Add(new Cat());
      }

      cats.AsParallel().ForAll(cat => cat.Name = "Carlo");

      foreach (var cat in cats)
      {
        Console.WriteLine(cat.Name);
      }

      Console.ReadLine();
    }
  }
}
于 2013-07-17T11:03:48.657 に答える