Un exemple simple nous montre que l'ordre n'est pas garanti d'être FIFO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication
{
class Program
{
private static Info info = new Info();
static void Main(string[] args)
{
Thread[] t1 = new Thread[5];
for (int i = 0; i < 5; i++)
{
t1[i] = new Thread(info.DoWork);
}
Thread[] t2 = new Thread[5];
for (int i = 0; i < 5; i++)
{
t2[i] = new Thread(info.Process);
}
for (int i = 0; i < 5; i++)
{
t1[i].Start();
t2[i].Start();
}
Console.ReadKey();
}
}
class Info
{
public object SynObject = new object();
public void DoWork()
{
Debug.Print("DoWork Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId);
lock (this.SynObject)
{
Debug.Print("Thread Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
Debug.Print("Thread Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId);
}
}
public void Process()
{
Debug.Print("Process Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId);
lock (this.SynObject)
{
Debug.Print("Process Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
Debug.Print("Process Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication
{
class Program
{
private static Info info = new Info();
static void Main(string[] args)
{
Thread[] t1 = new Thread[5];
for (int i = 0; i < 5; i++)
{
t1[i] = new Thread(info.DoWork);
}
Thread[] t2 = new Thread[5];
for (int i = 0; i < 5; i++)
{
t2[i] = new Thread(info.Process);
}
for (int i = 0; i < 5; i++)
{
t1[i].Start();
t2[i].Start();
}
Console.ReadKey();
}
}
class Info
{
public object SynObject = new object();
public void DoWork()
{
Debug.Print("DoWork Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId);
lock (this.SynObject)
{
Debug.Print("Thread Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
Debug.Print("Thread Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId);
}
}
public void Process()
{
Debug.Print("Process Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId);
lock (this.SynObject)
{
Debug.Print("Process Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
Debug.Print("Process Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId);
}
}
}
}
L'exécution se déroulera quelque chose comme ça
Process Lock Reached: 15
Process Lock Enter: 15
DoWork Lock Reached: 12
Process Lock Reached: 17
DoWork Lock Reached: 11
DoWork Lock Reached: 10
DoWork Lock Reached: 13
DoWork Lock Reached: 9
Process Lock Reached: 18
Process Lock Reached: 14
Process Lock Reached: 16
Process Lock Exit: 15
Thread Lock Enter: 9
Thread Lock Exit: 9
Process Lock Enter: 14
Process Lock Exit: 14
Thread Lock Enter: 10
Thread Lock Exit: 10
Thread Lock Enter: 11
Thread Lock Exit: 11
Process Lock Enter: 16
Process Lock Exit: 16
Thread Lock Enter: 12
Thread Lock Exit: 12
Process Lock Enter: 17
Process Lock Exit: 17
Thread Lock Enter: 13
Thread Lock Exit: 13
Process Lock Enter: 18
Process Lock Exit: 18
Comme vous pouvez le voir, le processus d'atteindre le verrou est différent de l'entrée dans le verrou.