アクセス数 累計:000,118,340 昨日:000,000,048 本日:000,000,020
|
|
|
|
【Amazon ランキング:ゲーム - PS Vita】
|
デットロックを回避するには、ロックをネストさせないのが一番の手ですが、どうしても複雑なロック制御を行わないといけない場合はデットロックを防止するため
Monitor.TryEntor メソッドを使用してタイムアウトするようにする方法があります。ただしその場合は処理にかかる時間を十分考慮してタイムアウト時間を設定する必要があります。
|
デットロック時のタイムアウト |
![](./contents/prg005/image/011_02.jpg) |
Form4 に Button を2つ貼り付けます。
|
|
VB[Form4.vb] |
Imports System.Threading
Public Class Form4
Private _lockObj1 As Object = New Object()
Private _lockObj2 As Object = New Object()
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles button1.Click
Dim th As Thread = New Thread(AddressOf ThreadProc1)
th.Start()
End Sub
Private Sub button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles button2.Click
Dim th As Thread = New Thread(AddressOf ThreadProc2)
th.Start()
End Sub
' スレッド1処理
Private Sub ThreadProc1()
For i As Integer = 0 To 100
Thread.Sleep(1000)
Console.WriteLine("Proc1:Object1 ロック")
If Monitor.TryEnter(_lockObj1, 1000) Then
Thread.Sleep(1000)
'------------------------------------------
Console.WriteLine("Proc1:Object2 ロック")
If Monitor.TryEnter(_lockObj2, 1000) Then
Thread.Sleep(1000)
Console.WriteLine("Proc1:Object2 解除")
Monitor.Exit(_lockObj2)
Else
Console.WriteLine("Proc1:Object2 ロック失敗!")
End If
'------------------------------------------
Thread.Sleep(1000)
Console.WriteLine("Proc1:Object1 解除")
Monitor.Exit(_lockObj1)
Else
Console.WriteLine("Proc1:Object1 ロック失敗!")
End If
Next
End Sub
' スレッド2処理
Private Sub ThreadProc2()
For i As Integer = 0 To 100
Thread.Sleep(500)
Console.WriteLine("Proc2:Object2 ロック")
If Monitor.TryEnter(_lockObj2, 1000) Then
Thread.Sleep(500)
'------------------------------------------
Console.WriteLine("Proc2:Object1 ロック")
If Monitor.TryEnter(_lockObj1, 1000) Then
Thread.Sleep(500)
Console.WriteLine("Proc2:Object1 解除")
Monitor.Exit(_lockObj1)
Else
Console.WriteLine("Proc2:Object1 ロック失敗!")
End If
'------------------------------------------
Thread.Sleep(500)
Console.WriteLine("Proc2:Object2 解除")
Monitor.Exit(_lockObj2)
Else
Console.WriteLine("Proc2:Object2 ロック失敗!")
End If
Next
End Sub
End Class
|
|
C#[Form4.cs] |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadCS
{
public partial class Form4 : Form
{
private object _lockObj1 = new object();
private object _lockObj2 = new object();
public Form4()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(ThreadProc1);
th.Start();
}
private void button2_Click(object sender, EventArgs e)
{
Thread th = new Thread(ThreadProc2);
th.Start();
}
// スレッド1処理
private void ThreadProc1()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
Console.WriteLine("Proc1:Object1 ロック");
if (Monitor.TryEnter(_lockObj1, 1000))
{
Thread.Sleep(1000);
//-------------------------------------
Console.WriteLine("Proc1:Object2 ロック");
if (Monitor.TryEnter(_lockObj2, 1000))
{
Thread.Sleep(1000);
Console.WriteLine("Proc1:Object2 解除");
Monitor.Exit(_lockObj2);
}
else
{
Console.WriteLine("Proc1:Object2 ロック失敗!");
}
//-------------------------------------
Thread.Sleep(1000);
Console.WriteLine("Proc1:Object1 解除");
Monitor.Exit(_lockObj1);
}
else
{
Console.WriteLine("Proc1:Object1 ロック失敗!");
}
}
}
// スレッド2処理
private void ThreadProc2()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(500);
Console.WriteLine("Proc2:Object2 ロック");
if (Monitor.TryEnter(_lockObj2, 1000))
{
Thread.Sleep(500);
//-------------------------------------
Console.WriteLine("Proc2:Object1 ロック");
if (Monitor.TryEnter(_lockObj1, 1000))
{
Thread.Sleep(500);
Console.WriteLine("Proc2:Object1 解除");
Monitor.Exit(_lockObj1);
}
else
{
Console.WriteLine("Proc2:Object1 ロック失敗!");
}
//-------------------------------------
Thread.Sleep(500);
Console.WriteLine("Proc2:Object2 解除");
Monitor.Exit(_lockObj2);
}
else
{
Console.WriteLine("Proc2:Object2 ロック失敗!");
}
}
}
}
}
|
|
実行 |
![](./contents/prg005/image/012_01.jpg) |
作成したプログラムを前回と同じ要領で実行すると、今回はフリーズせずに動作すると思います。時々ロックに失敗するのはデットロックが発生してタイムアウトが発生しているためです。
実際にプログラムを組む場合はタイムアウト発生時にリカバリを行うようにすると良いでしょう。 |
|
|
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※
|
【楽天 ランキング:スマートフォン】
|
|
|
|
このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。
|
ページの先頭に戻る |
Copyright© 2010-2015 Jun.Shiozaki All rights reserved. |
|
|
|