連載

プロフェッショナルVB.NETプログラミング

第31回 残されたいくつかのトピック(その2)

(株)ピーデー
川俣 晶
2003/01/11

Page1 Page2 Page3

マルチスレッドを同期するSyncLockステートメント

 この連載では、マルチスレッド機能については詳しく解説していない。これは、主にマルチスレッド機能はクラス・ライブラリを通じて提供されるものであり、この連載では膨大なクラス・ライブラリに深入りしないとしているためである。しかし、ステートメントとして用意された機能もあるので、それを紹介する。マルチスレッドの同期を取るためのSyncLockステートメントである。まず、マルチスレッドを安易に使ったがために、意図しない動作をするサンプル・プログラムを紹介する。フォーム上にボタンが1個貼り付けられている状態でのサンプル・プログラムである。

  1: Public Class Form1
  2:   Inherits System.Windows.Forms.Form
  3:
  4: …Windows フォーム デザイナで生成されたコード…
  5:
  6:   Private s As String = ""
  7:
  8:   Private Sub ThreadMain1()
  9:     Dim i As Integer
 10:     For i = 0 To 99999
 11:       s = s + "A"
 12:     Next
 13:     Trace.WriteLine("ThreadMain1 done")
 14:   End Sub
 15:
 16:   Private Sub ThreadMain2()
 17:     Dim i As Integer
 18:     For i = 0 To 99999
 19:       s = s + "A"
 20:     Next
 21:     Trace.WriteLine("ThreadMain2 done")
 22:   End Sub
 23:
 24:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 25:     Dim thread1 As New System.Threading.Thread(AddressOf ThreadMain1)
 26:     Dim thread2 As New System.Threading.Thread(AddressOf ThreadMain2)
 27:     thread1.Start()
 28:     thread2.Start()
 29:   End Sub
 30:
 31:   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 32:     Trace.WriteLine(Len(s))
 33:   End Sub
 34: End Class
マルチスレッドを安易に使ったため意図しない動作をするサンプル・プログラム11

 これを「ThreadMain1 done」と「ThreadMain2 done」というメッセージを確認してから、フォーム上のボタンを押すと、以下のような結果になった。この結果は条件により変化する可能性がある。

 1: 109646
サンプル・プログラム11の実行結果(例)

 このプログラムは、文字列に100000回1文字を追加するスレッドを2つ実行しているので、最終的な文字列の長さは200000文字になるはずである。しかし、そうなっていないのは、「s = s + "A"」という処理の途中でスレッドが切り替わる場合があるからだ。s + "A"の途中でスレッドが切り替わり、変数sを書き換えてしまえば、正しい長さになるはずがない。

 この問題を解消するために、SyncLockステートメントを使用することができる。これを使ったサンプル・プログラムを以下に示す。

  1: Public Class Form1
  2:   Inherits System.Windows.Forms.Form
  3:
  4: …Windows フォーム デザイナで生成されたコード…
  5:
  6:   Private s As String = ""
  7:
  8:   Private Sub ThreadMain1()
  9:     Dim i As Integer
 10:     For i = 0 To 99999
 11:       SyncLock Me
 12:         s = s + "A"
 13:       End SyncLock
 14:     Next
 15:     Trace.WriteLine("ThreadMain1 done")
 16:   End Sub
 17:
 18:   Private Sub ThreadMain2()
 19:     Dim i As Integer
 20:     For i = 0 To 99999
 21:       SyncLock Me
 22:         s = s + "A"
 23:       End SyncLock
 24:     Next
 25:     Trace.WriteLine("ThreadMain2 done")
 26:   End Sub
 27:
 28:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 29:     Dim thread1 As New System.Threading.Thread(AddressOf ThreadMain1)
 30:     Dim thread2 As New System.Threading.Thread(AddressOf ThreadMain2)
 31:     thread1.Start()
 32:     thread2.Start()
 33:   End Sub
 34:
 35:   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 36:     Trace.WriteLine(Len(s))
 37:   End Sub
 38: End Class
SyncLockステートメントを使用して排他的に処理するようにしたサンプル・プログラム12

 これを同様の手順で実行すると結果は以下のようになる。

 1: 200000
サンプル・プログラム12の実行結果

 意図とおりの結果が得られたことが分かるだろう。ここで注目すべき点は、11〜13行目と、21〜23行目のSyncLock文である。SyncLockに続いて記述されたオブジェクト(ここではMeつまりこのフォーム自身)に関するアクセスを調停してくれる。つまり、SyncLock〜End SyncLockの間を実行中のスレッドがあるとき、ほかのスレッドが同じオブジェクトに対するSyncLock文に遭遇すると、他スレッドの処理が終わるまで待たせるのである。これにより、s = s + "A"の処理の途中でほかのスレッドに切り替わり、変数sが書き変わることはなくなるのである。

次回予告

 今回に引き続き、次回も残されたいくつかのトピックについて見ていく。次回で本連載もとうとう最終回を迎えることになる。End of Article


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第31回 残されたいくつかのトピック(その2)
    1.値型と参照型/文字列の振る舞いの違い/プリミティブ型のエイリアス
    2.列挙型とその値/読み取り専用変数/複合代入ステートメント/条件付きメソッド
  3.マルチスレッドを同期するSyncLockステートメント
 
「プロフェッショナルVB.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間