A simple example tells us that order is not guaranteed by 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); } } } }
Execution will handle something like this
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
As you can see, the locking process is different from what is locked.
Tori
source share