关于C#的多线程方面

Posted chenggg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C#的多线程方面相关的知识,希望对你有一定的参考价值。

  class Program
    {
        static void Main(string[] args)
        {

            /**
             //前台线程和后台线程组成线程 所以每一个线程都有一个IsBackground
             //前台线程必须执行完程序才会退出
             //后台程序在程序退出时一并退出
             //当创建一个线程时默认是后台线程
             Console.WriteLine(Thread.CurrentThread.IsBackground);
             Console.WriteLine(Thread.GetCurrentProcessorId().ToString());


             Thread th = new Thread(_=>{
                 Thread t = _ as Thread;

                 //注释以后前台线程变后台线程 那么现在你在console.read之后程序直接执行完毕 不会再执行 "子线程结束" 
                 //t.IsBackground = true;
                 Console.WriteLine("子线程开始工作");
                 Console.WriteLine(t?.IsBackground);
                 Console.WriteLine(Thread.GetCurrentProcessorId().ToString());

                 //挂起线程取决于此条命令在哪个线程执行
                 Thread.Sleep(2000);
                 Console.WriteLine("子线程结束!");
             });


             th.Start(th);
             Thread.Sleep(1000);
             Console.WriteLine("主进程完毕");
             

             Console.Read();
             */

            //设置优先级(提供线程被调用的概率)
            // ThreadPriority();

            //Abort的使用
            //ThreadAbort();

            //ThreadJion();

            ThreadLock();


            Console.Read();
        }

        /// <summary>
        /// 线程优先级依赖于windows内部的线程调度
        /// 线程如果处于等待状态会释放掉他所持有的cpu 即使没有手动释放CPU也会被线程调度器抢占CPU
        /// 如果多个线程有相同的优先级 那么windows会为我们创建一个同优先级的队列然后循环执行
        /// 线程的优先级是动态调整的 所以低优先级的也会随着时间提升
        /// 也就是说 手动提升线程的优先级 对系统而言只是提高了被调用的概率
        /// </summary>
        static void ThreadPriority() {
            Thread thread = new Thread(()=> {
                Console.WriteLine("test thread");

            });
            Console.WriteLine(thread.Priority);
            thread.Start();
            thread.Priority = System.Threading.ThreadPriority.Highest;
            Console.WriteLine(thread.Priority);
            Console.Read();
        }

        static void ThreadAbort() {
            Thread t = new Thread(_=> {


                Console.WriteLine("线程:"+Thread.CurrentThread.Name+"  终止");

                try {
                    //使用Abort的方式停止线程会抛出异常
                    Thread.CurrentThread.Abort();
                }
                catch (Exception ex) {
                    //当Abort抛出异常时可以用ResetAbort取消停止
                    //可以尝试注释词条查看效果
                    Thread.ResetAbort();
                }
                Console.WriteLine("你看我打印不");


            });
            t.Name = "testThread";
            t.Start();
        }

        /// <summary>
        /// 阻塞其他线程(包括主线程) 直到找个线程执行完才会执行其他线程
        /// 通俗的说 就是这个join你放到哪个线程阻塞哪个线程
        /// </summary>
        static void ThreadJion() {

            Thread minThree = new Thread(() => print(3000, "线程minThread"));

            //挂2000
            Thread th = new Thread(()=>print(2000,"线程th"));
            //挂1000
            Thread th1 = new Thread(() => {
                minThree.Start();
                //让线程 minthree阻塞本线程
                minThree.Join();
                print(1000, "线程th1");
               
            });
            th.Start();
            th1.Start();

            //让th1阻塞主线程
            th1.Join();
            //此时minthree阻塞了th1  th先被打印了  而后打印了minthree 和 th1 再然后打印汉字  

            Console.WriteLine("我是主线程我想看看谁先执行完毕");
        }

        public static void print(int time,string str) {
            Thread.Sleep(time);
            Console.WriteLine(str);
        }

        /// <summary>
        /// lock关键字锁住某个资源让让线程有序使用
        /// </summary>
        public string name = "";
        public static void ThreadLock() {
            Program pg = new Program();
            pg.name = "尹程";

            //开两个线程抢下资源
            Thread t1 = new Thread(()=>printName(pg,"1"));
            Thread t2 = new Thread(() => printName(pg,"2"));
            t1.Start();
            //提升一下被调用的概率
            t1.Priority = System.Threading.ThreadPriority.AboveNormal;
            t2.Start();

        }
        private static object obj;

        public static void printName(object pg,string mark) {
            //锁住资源 注释掉lock多执行几次看看效果就明白了


            //锁住了所有program类的实例
            lock (typeof(Program)) {
                for (int i = 0; i < 3; i++)
                {
                    Console.WriteLine((pg as Program).name + "  " + mark);
                }
            }


            //我这里所著的是一个类的实例对象
            //不要锁字符串 字符串被C#特殊处理了  lock("某个字符串变量")与lock(typeof(string))是一样的效果
            lock (pg) {
               
            }

            //锁住一个私有静态的全局变量 
            //这样搞主要是为了静态的单例使用  
            //比如pureMVC把几个层的单例全部放在寄存器里读取 特意锁了个私有的静态变量 保证单例实例化的时候不会被其他线程同时执行
            lock (obj) {

            }

           
        }


        public static void AboutMonitor() {
            //lock在使用时会被CLR(C#的运行环境)解释为Monitor静态类
            //lock(obj){(这个括号相当于)
            Monitor.Enter(obj);


            //释放掉obj身上的锁 注意  解锁时 一定要在 Enter和Exit之间
            Monitor.Wait(obj);
            //只能锁Enter中锁住的资源
            Monitor.Pulse(obj);



            //} (这个括号相当于)
            Monitor.Exit(obj);

        }

    }

  

以上是关于关于C#的多线程方面的主要内容,如果未能解决你的问题,请参考以下文章

C# 中怎么使用带参数的多线程呢

对 C# 循环中的多线程感到困惑 [重复]

第13章 C#中的多线程

调用本机代码的多线程托管应用程序

关于 iPhone 上的多线程

我的多线程 HttpClient 有啥问题吗?