前进中的蜗牛

番茄大叔

水滴穿石,非一日之功;没有量变,何来质变。

.Net之美读书笔记16

多线程

一个应用程序至少包括一个进程,一个进程至少包括一个线程。程序需要在线程中执行,主线程由程序默认创建。单线程程序顺序执行,多线程程序同一时间可同时执行不同操作。

多线程的应用

线程的构造函数支持两种不同委托,一种不带参数的委托,一种带类型为object的一个参数。

 class Program
    {
        static void Main(string[] args)
        {
            ThreadStart ts = new ThreadStart(ThreadEntry);
            Thread worker = new Thread(ts);
            worker.Start();

            ParameterizedThreadStart pts = new ParameterizedThreadStart(ThreadEntry);
            Thread worker1 = new Thread(pts);
            worker1.Start("Item4");

            Console.WriteLine("Main Thread ends.");
            Console.ReadKey();
        }

        static void ThreadEntry()
        {
            SharedResource resource = new SharedResource();
            resource.Add("Item3");
        }

        static void ThreadEntry(object item)
        {
            SharedResource resource = new SharedResource();
            string strItem = (string)item;
            resource.Add(strItem);
        }
    }

    public class SharedResource
    {
        public List<string> list = new List<string> { "Item0", "Item1", "Item2" };
        public void Add(string item)
        {
            Console.WriteLine("Add" + item);
            list.Add(item);
        }
    }

线程的属性与方法

  • ManagedThreadId托管线程id,进程内唯一
  • Name线程名称,默认为空,开发者设置(不可修改)
  • ThreadState线程状态
  • Thread.CurrentThread获取当前线程
  • Thread.Sleep(1000);线程睡眠1s
  • worker.IsBackground = true;设置线程为后台线程,线程默认为前台线程,前台线程结束不管后台线程是否结束程序就会结束。
  • worker.Join();线程阻塞,等待worker线程执行结束

线程同步

CLR为每个线程分配了线程栈,用于保存本地变量,这样线程可以保证本地变量是独立的。但是线程外的变量对多线程是共享的。 针对多线程访问共享资源带来的问题两种解决方式 线程锁与线程通信


多线程同时访问变量问题:同时修改一个资源

        static void Print()
        {
            Console.WriteLine("i={0}",i);
            Thread.Sleep(1000);
             i++;
        }

        static void Main(string[] args)
        {
            ThreadStart ts1 = new ThreadStart(Print);
            Thread th1 = new Thread(ts1);
            th1.Start();
            Print();
            Console.ReadKey();
        }

线程锁

线程锁:同一时间只允许单个线程访问代码区域。

  static object olock = new object();

        static int i = 0;
        static void Main(string[] args)
        {
            ThreadStart ts1 = new ThreadStart(Print);
            Thread th1 = new Thread(ts1);
            th1.Start();
            Print();
            Console.ReadKey();
        }

        static void Print()
        {
            lock (olock)
            {
                Console.WriteLine("i={0}", i);
                Thread.Sleep(1000);
                i++;
            }
        }
  • lock只能接受引用变量,并且应该保证变量唯一。

线程信号

    public class Resource
    {
        public string Data;
    }

     class Program
    {
        private Resource res = new Resource();
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main";
            Program p = new Program();
            Thread worker = new Thread(p.ThreadEntry1);

            worker.Name = "Worker";
            worker.Start();

            lock (p.res)
            {
                if (string.IsNullOrEmpty(p.res.Data))
                {
                    //发送线程等待信号(Main线程等待)
                    Monitor.Wait(p.res);
                }

                Console.WriteLine("Data={0}",p.res.Data);
            }
            Console.ReadKey();
        }

        void ThreadEntry1()
        {
            lock (res)
            {
                res.Data = "Retrived";
                //发送线程开始执行信号(向主线程发送开始信号)
                Monitor.Pulse(res);
            }
        }
    }

线程的处理类

更多线程处理的类,请查看WaitHandle

posted @ 2018-01-17 22:22  LoveTomato  阅读(147)  评论(0编辑  收藏  举报