Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C#

C#のlockとは?意味や使い方とサンプルプログラムをご紹介

投稿日:2021年6月24日 更新日:

 

<目次>

(1) C#のlockとは?意味や使い方とサンプルプログラムをご紹介
 (1-1) 概要
 (1-2) 構文
 (1-3) サンプルプログラム
 (1-4) lockステートメントを使わないと・・

(1) C#のlockとは?意味や使い方とサンプルプログラムをご紹介

(1-1) 構文

lockステートメントはオブジェクトに対する相互排他(mutual exclusion)を行います。「相互排他」は、複数のプロセスで共有する資源で競合(同時アクセス)が発生した場合に、あるプロセスにて資源をロックして他プロセスが使用できないように排他する事で、データの整合性を保つ仕組みの事をいいます。

Javaでいう所の「synchronized」と同じようなものです。
 

(1-2) 構文

lockステートメントで指定したリソース(オブジェクト)に対して相互排他ロックを取得し、ブロック内({ }内)の処理を実行し、処理完了後にロックを解放します。

(構文)

lock ([ロック対象のオブジェクト])
{
	//# ロック取得後の処理
}

 

目次にもどる

(1-3) サンプルプログラム

●main文(スレッド生成・実行)

スレッド1(thr1)とスレッド2(thr2)を生成・処理実行するmain文です。LockCalc型の「lc」はロック対象のオブジェクト(1度に1スレッドのみロックを許可する)対象です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestProject
{
  class LockStatementTest
  {
    static void Main(string[] args)
    {
      //# ロック対象のオブジェクト
      LockCalc lc = new LockCalc();

      //# 各スレッドのインスタンス生成
      LockTask task1 = new LockTask(lc, 2);
      LockTask task2 = new LockTask(lc, 3);

      Thread thr1 = new Thread(new ThreadStart(task1.runCalc));
      Thread thr2 = new Thread(new ThreadStart(task2.runCalc));
      thr1.Start();
      thr2.Start();
    }
  }
}

 

目次にもどる

●クラス①:各スレッドの中で実行する処理のオブジェクト

各スレッドにて、累乗計算を起動するクラスです(スレッド処理のクラス)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestProject
{
  class LockTask
  {
    //# フィールド
    private LockCalc lc;
    private int calcTarget;

    //# コンストラクタ
    public LockTask(LockCalc lc, int calcTarget)
    {
      this.lc = lc;
      this.calcTarget = calcTarget;
    }

    //# 計算メソッドの呼び出し
    public void runCalc()
    {
      //# ■オブジェクトをロック
      lock (lc)
      {
        lc.calculate(calcTarget);
      }
    }
  }
}

 

目次にもどる

●クラス②:同期対象のオブジェクト

ロック対象の「LockCalc」クラスです(ただの累乗計算)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace TestProject
{
  class LockCalc
  {
    //# 計算メソッドの呼び出し
    public void calculate(int num)
    {
      for (int i = 1; i <= 5; i++)
      {
        Console.WriteLine("{0} の {1} 乗 = {2}", num, i, (int)Math.Pow(num, i));
        Thread.Sleep(100);
      }
    }
  }
}
 
実行結果は、まず1つ目のスレッド(thr1)の繰り返し計算が一通り行われて完了した後に、2つ目のスレッド(thr2)の計算が行われています。これはlockにより「LockCalc」クラスのオブジェクトをロックした結果です。

 

(図151)実行結果

目次にもどる

(1-4) lockステートメントを使わないと・・

次に上記のサンプルで「lock」ステートメントを指定せずに非同期処理にした例②をご紹介します。この例では「LockCalc」をlockしていないため、1つ目のスレッド(thr1)と2つ目のスレッド(thr2)の計算が交互に入り混じって出力されてしまっています。

変更箇所は1カ所だけで、スレッド処理(TestProject)のクラス内で使用している「LockCalc」のインスタンス「lc」に対して「lock」ステートメントを追加した以外は全て一緒です。
 
(lockなし版)
//# 計算メソッドの呼び出し
public void runCalc()
{
    lc.calculate(calcTarget);
}
 
(lockあり版)

//# 計算メソッドの呼び出し
public void runCalc()
{
    lock (lc)
    {
        lc.calculate(calcTarget);
    }
}

 

(図141)実行結果

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-C#

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

C#のvarの使いどころは?初めての方に向けてサンプルプログラムを使ってご紹介

<目次> (1) C#のvarの使いどころは?初めての方に向けてサンプルプログラムを使ってご紹介  (1-1) ArrayListに異なるデータ型が混在しているパターン  (1-2) LINQのクエリ …

C#のスレッド(Thread)とは?概要やサンプルプログラムをご紹介

  <目次> (1) C#のスレッド(Thread)とは?概要やサンプルプログラムをご紹介  (1-1) 概要   (1-1-1) スレッドのライフライクルについて   (1-1-2) ma …

C#のエラー「CS1069~このアセンブリへの参照を追加する事を検討してください」の対処方法+実際のソース例も掲載

<目次> (1) C#のエラー「CS1069~このアセンブリへの参照を追加する事を検討してください」の対処方法  (1-1) 発生状況・エラーメッセージ  (1-2) 原因  (1-3) 対処法 (1 …

Visual Studioのプロジェクトを別ソリューションに移動する手順

  <目次> (1) Visual Studioのプロジェクトを別ソリューションに移動する手順  (1-1) プロジェクトを別ソリューションに移動する手順  (1-2) 参考①:「.cspr …

Xamarin.Formsのプロジェクトを新規作成する手順

<目次> (1) Xamarin.Formsのプロジェクトを新規作成する手順  (1-1) Xamarin.Formsプロジェクトの作成   (1-1-1) プロジェクト新規作成   (1-1-2) …

  • English (United States)
  • 日本語
Top