C#的lock语句

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

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            Thread thread1 = new Thread(new ThreadStart(ThreadStart1));
            thread1.Name = "Thread1";
            Thread thread2 = new Thread(new ThreadStart(ThreadStart2));
            thread2.Name = "Thread2";
            Thread thread3 = new Thread(new ThreadStart(ThreadStart3));
            thread3.Name = "Thread3";

            thread1.Start();
            thread2.Start();
            thread3.Start();

            Console.ReadKey();
        }

        static object _object = new object();
        static void Done(int millisecondsTimeout)
        {
            Console.WriteLine(string.Format("{0} -> {1}.Start", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));

            //下边代码段同一时间只能由一个线程在执行
            lock (_object)
            {
                Console.WriteLine(string.Format("{0} -> {1}进入锁定区域.", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));

                Thread.Sleep(millisecondsTimeout);

                Console.WriteLine(string.Format("{0} -> {1}退出锁定区域.", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));
            }
        }

        static void ThreadStart1()
        {
            Done(5000);
        }

        static void ThreadStart2()
        {
            Done(3000);
        }

        static void ThreadStart3()
        {
            Done(1000);
        }

    }

}

运行效果如下:



如上边例子所示,lock语句保证了某个代码段同一时间只能由一个线程在执行,这在多线程编程中经常用到。msdn说明:lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区,如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

注意:应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:

·如果实例可以被公共访问,将出现 lock (this) 问题;
·如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题;
·由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock("myLock") 问题;

最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。

不使用lock示例

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

namespace ConsoleApplication1
{
    class Program
    {
        static string _str = string.Empty;

        static void Main(string[] args)
        {
            Thread thread1 = new Thread(new ThreadStart(ThreadStart1));
            thread1.Name = "Thread1";
            Thread thread2 = new Thread(new ThreadStart(ThreadStart2));
            thread2.Name = "Thread2";
            Thread thread3 = new Thread(new ThreadStart(ThreadStart3));
            thread3.Name = "Thread3";

            thread1.Start();
            thread2.Start();
            thread3.Start();

            Console.ReadKey();
        }

        static object _object = new object();
        static void Done(int millisecondsTimeout)
        {
            //不锁定
            //lock (_object)
            //{
                _str = Thread.CurrentThread.Name;
                Console.WriteLine(string.Format("{0} -> {1}线程将_str赋值为{1}.", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));

                Thread.Sleep(millisecondsTimeout);

                Console.WriteLine(string.Format("{0} -> {1}线程输出_str:{2}.", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name, _str));
            //}
        }

        static void ThreadStart1()
        {
            Done(5000);
        }

        static void ThreadStart2()
        {
            Done(3000);
        }

        static void ThreadStart3()
        {
            Done(1000);
        }

    }

}



谁都可以修改_str的值,程序运行结果将没有保障!

评论: 0 | 引用: 0 | 查看次数: 5661
发表评论
登录后再发表评论!