C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#でハッシュテーブルの同期ラッパーを作成する方法

C# の Hashtable は、既定の状態ではスレッドセーフではありません。マルチスレッド環境で安全にコレクションを操作したい場合は、静的メソッドである Hashtable.Synchronized() を使用して、元のコレクションを包む同期(スレッドセーフ)ラッパーを作成します。この記事では、実際のコード例をもとに、同期ラッパーの作成方法と IsSynchronized プロパティによる確認方法を解説します。

通常の Hashtable の動作を確認する

まずは、同期化されていない通常の Hashtable を作成し、要素を追加した後、IsSynchronized プロパティの値を出力してみましょう。

サンプルコード

using System;
using System.Collections;
public class Demo {
   public static void Main() {
      Hashtable hash = new Hashtable();
      hash.Add("1", "AB");
      hash.Add("2", "CD");
      hash.Add("3", "EF");
      hash.Add("4", "GH");
      hash.Add("5", "IJ");
      hash.Add("6", "KL");
      Console.WriteLine("Hashtable elements...");
      foreach(DictionaryEntry d in hash) {
         Console.WriteLine("Key = "+d.Key + ", Value = " + d.Value);
      }
      Console.WriteLine("Hashtable is synchronized? = "+hash.IsSynchronized);
   }
}

実行結果

Hashtable elements...
Key = 1, Value = AB
Key = 2, Value = CD
Key = 3, Value = EF
Key = 4, Value = GH
Key = 5, Value = IJ
Key = 6, Value = KL
Hashtable is synchronized? = False

実行結果から、通常の Hashtable に対して IsSynchronized プロパティを参照すると False が返されることがわかります。つまり、この状態のコレクションはスレッドセーフではないため、複数のスレッドから同時に読み書きを行うと、データ競合や不整合が発生する恐れがあります。

Synchronized() メソッドで同期ラッパーを作成する

次に、Hashtable.Synchronized() メソッドを使って、同期ラッパーを作成する例を見てみましょう。このメソッドは、元の Hashtable を引数に受け取り、スレッドセーフなラッパーオブジェクトを返します。

サンプルコード

using System;
using System.Collections;
public class Demo {
   public static void Main() {
      Hashtable hash = new Hashtable();
      hash.Add("1", "Mark");
      hash.Add("2", "Gary");
      hash.Add("3", "Jacob");
      hash.Add("4", "Andy");
      hash.Add("5", "Jack");
      Console.WriteLine("Hashtable elements...");
      foreach(DictionaryEntry d in hash) {
         Console.WriteLine("Key = "+d.Key + ", Value = " + d.Value);
      }
      Console.WriteLine("Hashtable is synchronized? = "+hash.IsSynchronized);
      Hashtable hash2 = Hashtable.Synchronized(hash);
      Console.WriteLine("Hashtable is synchronized? = "+hash2.IsSynchronized);
   }
}

実行結果

Hashtable elements...
Key = 1, Value = Mark
Key = 2, Value = Gary
Key = 3, Value = Jacob
Key = 4, Value = Andy
Key = 5, Value = Jack
Hashtable is synchronized? = False
Hashtable is synchronized? = True

ポイントのまとめ

  • 元の hash オブジェクト自体は同期化されておらず、IsSynchronized は引き続き False を返します。
  • Hashtable.Synchronized(hash) が返す新しいオブジェクト hash2 が同期ラッパーであり、こちらの IsSynchronizedTrue を返します。
  • マルチスレッド環境では、必ずこの同期ラッパー経由でコレクションにアクセスしてください。元のオブジェクトを直接操作すると、同期の保証は失われます。
  • 列挙処理(foreach など)自体はスレッドセーフではないため、列挙中に他のスレッドがコレクションを変更する可能性がある場合は、読み取り側でも明示的にロックを行う必要があります。

このように、Hashtable.Synchronized() メソッドを利用することで、既存の Hashtable を簡単にスレッドセーフなコレクションとして扱うことができます。

  1. Linuxで音楽制作・録音に使えるおすすめアプリ6選

    Linuxユーザーと聞くと、プログラマーやシステム管理者など、技術寄りの人たちをイメージする方が多いかもしれません。確かにLinuxはそうしたユーザーに最適なOSですが、それだけがLinuxの魅力ではありません。実は、クリエイティブな作業をする人にとっても、Linuxは技術者と同じくらい快適な環境を提供してくれるのです。予算を抑えたいミュージシャンにとって、Linuxは非常に魅力的な選択肢です。無料で使える音楽制作アプリが豊富に揃っており、楽譜の作曲からアルバムのミキシングまで、目的に合ったソフトウェアがきっと見つかります。1. ArdourArdourはLinuxネイティブのデジタルオーディ

  2. すべての人に届くCockroachDB――マネージドサービスがついに一般提供(GA)へ

    2019年9月30日にObjectRocket.com/blogにて初公開 DBaaS(Database as a Service)の価値を理解していながらも、これまでCockroachDBのマネージドサービスは多くのユーザーにとって手の届かない存在でした。Rackspace ObjectRocketの「Managed CockroachDB」なら、約21ドル/GBという手頃な価格でCockroachDBのパワーを活用できます。24時間365日体制の専門チームによる完全なSLA(サービスレベル契約)が付帯し、エンタープライズレベルの機能をすべて備えています。 1年余り前、私たち