C#中lock,Monitor,Mutex多线程同步应用实例比较

C#中可以使用Monitor类、lock和Mutex类来进行多线程的同步。具体的应用实例比较代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        #region variable
        Thread thread1 = null;
        Thread thread2 = null;
        Mutex mutex = null;


        private static Object sto = new Object();//私有静态锁定对象
        #endregion


        static void Main(string[] args)
        {
            Program p = new Program();
            p.RunThread();
            Console.ReadLine();
        }
        public Program()
        {
            mutex = new Mutex();
            //演示无同步的情况
            //thread1 = new Thread(new ThreadStart(thread1Func));
            //thread2 = new Thread(new ThreadStart(thread2Func));


            //演示使用lock同步线程3和4,并使线程3和4按照调用顺序来依次执行
            thread1 = new Thread(new ThreadStart(thread3Func));
            thread2 = new Thread(new ThreadStart(thread4Func));


            //演示使用Monitor同步线程5和6,并使线程5和6按照调用顺序来依次执行
            //thread1 = new Thread(new ThreadStart(thread5Func));
            //thread2 = new Thread(new ThreadStart(thread6Func));


            //演示使用Mutex同步线程7和8,但不能同步线程7或8中for循环的执行
            //thread1 = new Thread(new ThreadStart(thread7Func));
            //thread2 = new Thread(new ThreadStart(thread8Func));





            //演示使用lock同步线程33和44,并先执行完线程33后,再执行线程44
            //thread1 = new Thread(new ThreadStart(thread33Func));
            //thread2 = new Thread(new ThreadStart(thread44Func));   


            //演示使用Monitor同步线程55和66,并先执行完线程55后,再执行线程66
            //thread1 = new Thread(new ThreadStart(thread55Func));
            //thread2 = new Thread(new ThreadStart(thread66Func));


            //演示使用Mutex同步线程77和88,并先执行完线程77后,再执行线程88
            //thread1 = new Thread(new ThreadStart(thread77Func));
            //thread2 = new Thread(new ThreadStart(thread88Func));




            
        }
        public void RunThread()
        {
            thread1.Start();
            thread2.Start();
        }


        private void TestFunc(string str)
        {
            Console.WriteLine("{0} {1}", str, System.DateTime.Now.ToLongTimeString() + ":" + System.DateTime.Now.Millisecond.ToString());
            Thread.Sleep(50);
        }


        //无同步的情况
        private void thread1Func()
        {
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread1 have run " + count.ToString() + " times");
                Thread.Sleep(50);
            }
        }
        private void thread2Func()
        {
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread2 have run " + count.ToString() + " times");
                Thread.Sleep(100);
            }
        }


        //使用lock同步线程3和4,并使线程3和4按照调用顺序来依次执行
        private void thread3Func()
        {
            for (int count = 0; count < 10; count++)
            {
                lock (sto)
                {
                    TestFunc("Thread3 have run " + count.ToString() + " times");
                    Thread.Sleep(50);
                }
            }
        }


        private void thread4Func()
        {
            for (int count = 0; count < 10; count++)
            {
                lock (sto)
                {
                    TestFunc("Thread4 have run " + count.ToString() + " times");
                    Thread.Sleep(100);
                }
            }
        }



        //使用lock同步线程33和44,并先执行完线程33后,再执行线程44
        private void thread33Func()
        {
            lock (sto)
            {
                for (int count = 0; count < 10; count++)
                {
                    TestFunc("Thread33 have run " + count.ToString() + " times");
                    Thread.Sleep(50);
                }
            }
        }


        private void thread44Func()
        {
            lock (sto)
            {
                for (int count = 0; count < 10; count++)
                {
                    TestFunc("Thread44 have run " + count.ToString() + " times");
                    Thread.Sleep(100);
                }
            }
        }



        //使用Mutex同步线程7和8,但不能同步线程7或8中for循环的执行
        private void thread7Func()
        {
            for (int count = 0; count < 10; count++)
            {
                mutex.WaitOne();
                TestFunc("Thread7 have run " + count.ToString() + " times");
                Thread.Sleep(50);
                mutex.ReleaseMutex();
               
            }
        }


        private void thread8Func()
        {
            for (int count = 0; count < 10; count++)
            {
                mutex.WaitOne();
                TestFunc("Thread8 have run " + count.ToString() + " times");
                Thread.Sleep(100);
                mutex.ReleaseMutex();


            }
        }


        //使用Mutex同步线程77和88,并先执行完线程77后,再执行线程88
        private void thread77Func()
        {
            mutex.WaitOne();
            for (int count = 0; count < 10; count++)
            {                
                TestFunc("Thread77 have run " + count.ToString() + " times");
                Thread.Sleep(50);
            }
            mutex.ReleaseMutex();
        }


        private void thread88Func()
        {
            mutex.WaitOne();
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread88 have run " + count.ToString() + " times");
                Thread.Sleep(100);               
            }
            mutex.ReleaseMutex();


        }



        //使用Monitor同步线程5和6,并使线程5和6按照for循环的调用顺序来依次执行
        //Monitor和Lock可以互斥本线程的重复调用
        private void thread5Func()
        {
            for (int count = 0; count < 10; count++)
            {                
                Monitor.Enter(sto);
                TestFunc("Thread5 have run " + count.ToString() + " times");
                Thread.Sleep(50); 
                Monitor.Exit(sto);                
            }
        }






        
        private void thread6Func()
        {
            for (int count = 0; count < 10; count++)
            {
                Monitor.Enter(sto);
                TestFunc("Thread6 have run " + count.ToString() + " times");
                Thread.Sleep(100); 
                Monitor.Exit(sto);
                
            }
        }


        //使用Monitor同步线程55和66,并先执行完线程55后,再执行线程66
        private void thread55Func()
        {
            Monitor.Enter(sto);
            for (int count = 0; count < 10; count++)
            { 
                TestFunc("Thread55 have run " + count.ToString() + " times");
                Thread.Sleep(50);                
            }
            Monitor.Exit(sto);
        }


        private void thread66Func()
        {
            Monitor.Enter(sto);
            for (int count = 0; count < 10; count++)
            { 
                TestFunc("Thread66 have run " + count.ToString() + " times");
                Thread.Sleep(100);
            }
            Monitor.Exit(sto);


        }
    }

}

具体输出分析如下:

1.无同步的输出效果:


2个线程同时开始执行;2个线程从第1次往后,thread1的执行间隔约是100thread2的执行间隔约是150

 

2.lock同步的输出效果:

使用lock同步线程3和4,并使线程3和4按照for循环调用顺序来依次执行。

 

 

 

3.Monitor同步的输出效果:

使用Monitor同步线程5和6,并使线程5和6按照for循环调用顺序来依次执行。

 

4. Mutex同步的输出效果:

Mutex同步线程7和8,但不能同步线程7或8中for循环的执行顺序。

 

5. Mutex同步线程33和44的输出效果:

使用lock同步线程33和44,并先执行完线程33后,再执行线程44。

 

6. Mutex同步线程55和66的输出效果:

使用Monitor同步线程55和66,并先执行完线程55后,再执行线程66。

 

7. Mutex同步线程77和88的输出效果:

使用Mutex同步线程77和88,并先执行完线程77后,再执行线程88。


应用实例比较结果:

(1)Mutex只能互斥不同线程间的调用,但是不能互斥本线程的重复调用。
(2)monitor和lock不但能互斥本线程(防止本线程重入),也能互斥其他线程的重复调用。(注意锁定对象的设定)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值