zoukankan      html  css  js  c++  java
  • 多线程实战(一) 线程基础

    线程的好处,我想都不必多说,博客园太多了;但个人对线程了解还比较基础,决定把学习线程记录下来(有一些例子来之博客园):

    创建线程

    暂停线程

    等待线程

    线程传参数

    lock

    Monitor

    创建线程

    Thread t = new Thread(PrintNumbers);//线程创建
    t.Start();//开始线程
    PrintNumbers();
    static void PrintNumbers() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Console.WriteLine(i); } }

    暂停线程

    sleep暂停线程;

    Thread t = new Thread(PrintNumbersWithDelay);
                t.Start();
    
    
    static void PrintNumbersWithDelay()
            {
                Console.WriteLine("Starting...");
                for (int i = 1; i < 10; i++)
                {
                    Thread.Sleep(2000);
                    Console.WriteLine(string.Format("顺序{0},时间:{1}", i, DateTime.Now));
                }
            }

    sleep(2000);每隔2秒输出一次;

    等待线程

      Thread t = new Thread(Run);
    
            t.Start();
    
            //Join相当于把Run方法内嵌如此
            t.Join();
    
            //该死的t.Join(),害的我主线程必须在你执行完后才能执行。
            Console.WriteLine("我是主线程:" + Thread.CurrentThread.GetHashCode());
        }
    
        static void Run()
        {
            //等待5s
            Thread.Sleep(5000);
    
            Console.WriteLine("我是线程:" + Thread.CurrentThread.GetHashCode());
        }

    线程传参数

     var threadOne = new Thread(One);
                threadOne.Start("one");
                threadOne.Join();
                var threadTwo = new Thread(() => One("two"));
                threadTwo.Start();
                threadTwo.Join();
                var value = "three";
                var threadThree = new Thread(() => One(value));
                value = "four";
                var threadFour = new Thread(() => One(value));
                threadThree.Start();
                threadFour.Start();
    
    
    static void One(object obj)
            {
                Console.WriteLine(obj);
            }

    在启动线程3,4时,变量value的值变成four,最后打印出four

    lock

    Console.WriteLine("不规则统计");
                var c = new Counter();
                var t1 = new Thread(() => TestCounter(c));
                var t2 = new Thread(() => TestCounter(c));
                var t3 = new Thread(() => TestCounter(c));
                t1.Start();
                t2.Start();
                t3.Start();
                t1.Join();
                t2.Join();
                t3.Join();
                Console.WriteLine("总计: {0}",c.Count);
                Console.WriteLine("--------------------------");
                Console.WriteLine("正确统计");
                var c1 = new CounterWithLock();
                t1 = new Thread(() => TestCounter(c1));
                t2 = new Thread(() => TestCounter(c1));
                t3 = new Thread(() => TestCounter(c1));
                t1.Start();
                t2.Start();
                t3.Start();
                t1.Join();
                t2.Join();
                t3.Join();
                Console.WriteLine("总计: {0}", c1.Count);
    
    static void TestCounter(CounterBase c)
            {
                for (int i = 0; i < 100000; i++)
                {
                    c.Increment();
                    c.Decrement();
                }
            }
    
            class Counter : CounterBase
            {
                public int Count { get; private set; }
    
                public override void Increment()
                {
                    Count++;
                }
    
                public override void Decrement()
                {
                    Count--;
                }
            }
    
            class CounterWithLock : CounterBase
            {
                private readonly object _syncRoot = new Object();
    
                public int Count { get; private set; }
    
                public override void Increment()
                {
                    lock (_syncRoot)
                    {
                        Count++;
                    }
                }
    
                public override void Decrement()
                {
                    lock (_syncRoot)
                    {
                        Count--;
                    }
                }
            }
    
            abstract class CounterBase
            {
                public abstract void Increment();
    
                public abstract void Decrement();
            }

    加了锁和不加锁统计的结果完全不一样

    Monitor

    同步访问对象机制;在锁定的临界区中只允许让一个线程访问,其他线程排队等待。

    1:Monitor.Enter和Monitor.Exit

     for (int i = 0; i < 10; i++)
                {
                    Thread t = new Thread(Run);
    
                    t.Start();
                }
    
    //资源
            static object obj = new object();
    
            static int count = 0;
    
            static void Run()
            {
                Thread.Sleep(10);
    
                //进入临界区
                Monitor.Enter(obj);
    
                Console.WriteLine("当前数字:{0}", ++count);
    
                //退出临界区
                Monitor.Exit(obj);
            }

    2:Monitor.Wait和Monitor.Pulse

     Wait: 暂时的释放资源锁,然后该线程进入”等待队列“中,那么自然别的线程就能获取到资源锁。

     Pulse:  唤醒“等待队列”中的线程,那么当时被Wait的线程就重新获取到了锁。

     public class Program
        {
            public static void Main(string[] args)
            {
                LockObj obj = new LockObj();
    
                //注意,这里使用的是同一个资源对象obj
                Jack jack = new Jack(obj);
                John john = new John(obj);
    
                Thread t1 = new Thread(new ThreadStart(jack.Run));
                Thread t2 = new Thread(new ThreadStart(john.Run));
    
                t1.Start();
                t1.Name = "Jack";
    
                t2.Start();
                t2.Name = "John";
    
                Console.ReadLine();
            }
        }
    
        //锁定对象
        public class LockObj { }
    
        public class Jack
        {
            private LockObj obj;
    
            public Jack(LockObj obj)
            {
                this.obj = obj;
            }
    
            public void Run()
            {
                Monitor.Enter(this.obj);
    
                Console.WriteLine("{0}:我已进入茅厕。", Thread.CurrentThread.Name);
    
                Console.WriteLine("{0}:擦,太臭了,我还是撤!", Thread.CurrentThread.Name);
    
                //暂时的释放锁资源
                Monitor.Wait(this.obj);
    
                Console.WriteLine("{0}:兄弟说的对,我还是进去吧。", Thread.CurrentThread.Name);
    
                //唤醒等待队列中的线程
                Monitor.Pulse(this.obj);
    
                Console.WriteLine("{0}:拉完了,真舒服。", Thread.CurrentThread.Name);
    
                Monitor.Exit(this.obj);
            }
        }
    
        public class John
        {
            private LockObj obj;
    
            public John(LockObj obj)
            {
                this.obj = obj;
            }
    
            public void Run()
            {
                Monitor.Enter(this.obj);
    
                Console.WriteLine("{0}:直奔茅厕,兄弟,你还是进来吧,小心憋坏了!",
                                   Thread.CurrentThread.Name);
    
                //唤醒等待队列中的线程
                Monitor.Pulse(this.obj);
    
                Console.WriteLine("{0}:哗啦啦....", Thread.CurrentThread.Name);
    
                //暂时的释放锁资源
                Monitor.Wait(this.obj);
    
                Console.WriteLine("{0}:拉完了,真舒服。", Thread.CurrentThread.Name);
    
                Monitor.Exit(this.obj);
            }
        }

  • 相关阅读:
    洛谷P4113 [HEOI2012]采花
    洛谷P5159 WD与矩阵
    洛谷P1262 间谍网络
    洛谷P3038 牧草种植Grass Planting
    洛谷P3258 [JLOI2014]松鼠的新家
    洛谷P2294 [HNOI2005]狡猾的商人
    洛谷P4878 [USACO05DEC]layout布局
    【CF1132F】Clear the String (DP)
    [AH2017/HNOI2017]大佬(动态规划 搜索)
    「NOI2018」屠龙勇士(CRT)
  • 原文地址:https://www.cnblogs.com/xchit/p/4777087.html
Copyright © 2011-2022 走看看