Are threads waiting on a lock FIFO?

后端 未结 5 1895
被撕碎了的回忆
被撕碎了的回忆 2021-01-05 03:13

Let\'s say I have the following code

static class ...
{
    static object myobj = new object();

    static void mymethod()
    {
        lock(myobj)
                


        
5条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-05 03:52

    A simple example tell us that order is not guaranteed to be 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 procede 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 ca see the process of reach lock is different that lock enter.

提交回复
热议问题