多线程同步与锁

多线程同步与锁

本次主要讨论的是lock,autoeventset,moniter

代码如下

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


namespace ConsoleApplication1
{
    class Program
    {
        private static AutoResetEvent autoReset = new AutoResetEvent(false);
        static int countNum = 0;                        //计数器
        static object lockobj = new object();           //静态锁对象

        static void Main(string[] args)
        {
            // test AutoResetEvent and Lock object or static object begin
            Thread thread1 = new Thread(new ParameterizedThreadStart(wirte1));
            thread1.Start(1);
            Thread thread2 = new Thread(wirte1);
            thread2.Start(2);
            //--- test end---

            // test Monitor begin
            //Thread thread3 = new Thread(wirte2);
            //thread3.Start(3);
            //Thread thread5 = new Thread(wirte2);
            //thread5.Start(5);
            // -- end ---
            Thread thread4 = new Thread(new ThreadStart(wirte4));
            thread4.Start();

            Console.ReadLine();
        }
        public static void wirte1(object index)
        {
            autoReset.WaitOne();                //阻塞,直到收到信号
            Console.WriteLine(index.ToString() + " enter lock before");
            //lock (new object())       //这样锁可以一次只能一个线程进入锁定的代码块,但一次过后可以其它的线程的抢到
            lock (lockobj)              //锁定后只有一个线程进入直至块内代码执行完
            {
                Console.WriteLine(index.ToString() + " enter lock after");
                while (countNum < 50)
                {


                    Console.WriteLine(countNum.ToString() + " index:" + index.ToString());
                    Thread.Sleep(500);
                    //autoReset.Reset();

                    countNum++;
                }
            }
            //autoReset.Set();
        }
        public static void wirte2(object index)
        {
            bool isrealse = false;
            lock (lockobj)
            {
               
                Console.WriteLine(index.ToString() + " enter lock after");
                while (countNum < 50)
                {

                    if (isrealse)
                    {
                        Monitor.Wait(lockobj);                  //阻塞当前线程
                    }
                    Console.WriteLine(countNum.ToString() + " index:" + index.ToString());
                    Thread.Sleep(500);
                    //autoReset.Reset();

                    countNum++;
                    if (countNum > 27)
                    {
                        Monitor.PulseAll(lockobj);              //取消阻塞,并且当前lock无效

                    }
                    if (countNum > 30)
                    {
                        isrealse = true;
                    }


                }
            }
        }
        public static void wirte3()
        {
            for (int i = 0; i < 30; i++)
            {
                Console.WriteLine(i.ToString() + " thread3");
                Thread.Sleep(500);

            }
        }
        public static void wirte4()
        {
            lock (lockobj)
            {
                for (int i = 0; i < 30; i++)
                {
                    Console.WriteLine(i.ToString() + " thread4");
                    Thread.Sleep(500);
                    if (i > 25)
                    {
                        autoReset.Set();        //置信号为true,阻塞的线程可以运行
                    }

                }
            }
        }
    }
}

 

上图为线程1,2执行write1,被阻塞,直到线程4发出信号,线程1,2收到信号后取得执行权的线程可以运行

 

改下main

 static void Main(string[] args)
        {
            // test AutoResetEvent and Lock object or static object begin
            //Thread thread1 = new Thread(new ParameterizedThreadStart(wirte1));
            //thread1.Start(1);
            //Thread thread2 = new Thread(wirte1);
            //thread2.Start(2);
            //--- test end---

            // test Monitor begin
            Thread thread3 = new Thread(wirte2);
            thread3.Start(3);
            Thread thread5 = new Thread(wirte2);
            thread5.Start(5);
            // -- end ---
            Thread thread4 = new Thread(new ThreadStart(wirte4));
            thread4.Start();

            Console.ReadLine();
        }

上图为线程3,5执行write2,线程4执行wirte4,首先取得lock的先执行,如果线程4取得锁,则需等待其执行完,如果线程3,5先取得lock则到>30后则阻塞,但在>27时Monitor.PulseAll(lockobj); 已取消阻塞且lock已没起作用,所以 Monitor.Wait(lockobj);起不到阻塞作用(很大概率),如果write2只有一个线程执行,则到〉30时一定会阻塞

 

总结:
1 lock new object 只对当前有效,随后所有等待线程都有可能获得锁

2 lock static object 多个线程如是用同一对象锁,则先获取的运行,其它的等待

3 AutoResetEvent waitone阻塞,set释放信号,被阻塞的线程可以获得运行权

4  Monitor.PulseAll(lockobj); 取消阻塞,且当前lock释放

5 Monitor.Wait(lockobj); 阻塞当前线程,

 

以上是vs2008,win7下的测试结果,如果有发现有误的请指正,以免误导大家,多谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值