C# 多线程编程——线程同步(二)

前言

        在编程的时候,有时会使用多线程来解决问题,比如你的程序需要在后台处理一大堆数据,但还要使用户界面处于可操作状态;或者你的程序需要访问一些外部资源如数据库或网络文件等。这些情况你都可以创建一个子线程去处理,然而,多线程不可避免地会带来一个问题,就是线程同步的问题,即要通过线程同步编写出安全且高效的多线程的多线程程序。

一、线程安全与锁

        线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时对一个变量执行读写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

二、实例介绍

1、lock锁机制

    public class Program
    {
        private object locker = new object();
        int num = 1;

        public static void Main(string[] args)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();//开始计时

            Program program = new Program();
            ThreadStart threadStart = new ThreadStart(program.Run);//Run--对象引用对非静态的方法Run,使用program.Run是必要的

            for (int i = 0; i < 5; i++)
            {
                Thread thread = new Thread(threadStart);
                thread.Start();
            }

            program.num++;
            Console.WriteLine("num is:" + program.num);
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());

            //停止计时
            stopWatch.Stop();

            //输出执行的时间,毫秒数
            Console.WriteLine("The execution time is " + stopWatch.ElapsedMilliseconds + " milliseconds.");
            Console.ReadKey();
        }

        public void Run()
        {
            lock (locker)
            {
                num++;
                Console.WriteLine("num is:" + num);
                Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            }
        }

执行结果:

C# 多线程编程——线程同步(二)_第1张图片

        lock 是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的。可以看到这种方式的确没有阻塞主线程,而且成员变量的值也是连续递增的,说明是线程安全的。lock 锁机制表示在同一时刻只有一个线程可以锁定同步对象(在这里是locker),任何竞争的的其它线程都将被阻止,直到这个锁被释放。

        lock 的参数必须是基于引用类型的对象,不要是基本类型,比如 bool、int,这样根本不能同步,原因是lock的参数要求是对象,如果传入 int,势必要发生装箱操作,这样每次lock的都将是一个新的不同的对象。最好避免使用public类型或不受程序控制的对象实例,因为这样很可能导致死锁。永远也不要 lock 一个字符串。

应该注意以下几点: 

  1)如果一个类的实例是public的,最好不要lock(this)。因为使用你的类的人也许不知道你用了lock,如果他new了一个实例,并且对这个实例上锁,就很容易造成死锁。

  2)如果MyType是public的类型,不要lock(typeof(MyType))

  3)永远也不要lock一个字符串

2、其它的几种同步方法

Monitor类、Mutex类、同步事件和等待句柄

以后抽时间再写

 

参考文章:

https://www.cnblogs.com/Brambling/p/7174597.html

http://www.cnblogs.com/yank/p/3227324.html

http://www.cnblogs.com/SkySoot/archive/2012/04/02/2430295.html

https://www.cnblogs.com/dingfangbo/p/5769501.html

你可能感兴趣的:(@编程语言:.NET_C#)