C#线程学习,线程的创建,线程的暂停,线程的锁lock,Monitor,线程使用中的注意事项(一)

C#线程学习,线程的创建,线程的暂停,线程的锁lock,Monitor,线程使用中的注意事项(一)

八股文

线程和进程

进程是指程序的一次执行过程,而线程是指进程中执行的一条单一逻辑控制流。
进程是由多个线程组成的,一个进程至少有一个线程,叫做主线程。可以在任务管理器中查看有几个线程,几个进程。
C#中的线程不支持获取返回值,如果想获取返回时需要使用task

Foreground线程和Background线程

Foreground默认的, 只要有一个Foregournd线程在执行,应用程序就不会关闭。Background线程则不是,程序一旦退出Background立刻关闭。通过IsBackground查看属性

注意事项

  1. 异常捕获代码应该写在线程代码的内部,而不是调用的位置
  2. 同一个变量如果在两个线程修改那么另外一个也会修改,不同的线程是共享全局变量的

代码

  1. 线程的创建
  2. 线程间的变量共享
  3. 线程中使用lock进行锁,解决线程中变量共享的问题
  4. 线程中使用Monitor进行锁,解决线程中变量共享的问题
using System;
using System.Threading;
using static System.Net.Mime.MediaTypeNames;

namespace csharp线程学习
{
    internal class Program
    {
        static void Main(string[] args)
        {
              线程的创建
       //Console.WriteLine("\n线程的创建");
       //CreatMyThread_1();//无参数
       //CreatMyThread_2();//有参数
       //CreatMyThread_3();//有参数
       //CreatMyThread_4();//使用lamada表达式

       两个线程共享全局变量
       Console.WriteLine("\n线程中,全局变量是共享的");
       //Thread thread1 = new Thread(Func1);
       //thread1.Start();
       //Thread thread2 = new Thread(Func2);
       //thread2.Start();

       //使用线程锁,来解决变量共享的问题
       Console.WriteLine("\n线程中,使用lock线程锁");
       //Thread thread1 = new Thread(ThreadLine1);
       //thread1.Start();
       //Thread thread2 = new Thread(ThreadLine2);
       //thread2.Start();

       //使用线程锁,
       Console.WriteLine("\n线程中,使用Monitor线程锁");
       Thread thread1 = new Thread(ThreadLine4);
       thread1.Start();
       Thread thread2 = new Thread(ThreadLine5);
       thread2.Start();
           
          		  Console.ReadLine();
                 Console.ReadLine();
        }


        /// 
        /// 创建线程的方式_1
        /// 
        private static void CreatMyThread_1()
        {
            //创建线程的方式
            Thread thread = new Thread(ThreadProc);
            thread.Start();
        }

        /// 
        /// 创建线程的方式有参数_2s
        /// 
        private static void CreatMyThread_2()
        {
            Thread m_thrad = new Thread(new ParameterizedThreadStart(ThreadProcWithPro));//创建一个有参数的线程
            m_thrad = new Thread(ThreadProcWithPro);
            m_thrad.Start("今天是2023年");
        }

        /// 
        /// 创建线程的方式有参数_3
        /// 
        private static void CreatMyThread_3()
        {
            Thread m_thrad = new Thread(ThreadProcWithPro);//创建一个有参数的线程
            m_thrad.Start("今天是2023年");
        }

        /// 
        /// 创建线程的方式有参数_4
        /// 
        private static void CreatMyThread_4()
        {
            Thread t = new Thread(() => Console.WriteLine("Hello!"));
        }

        private static void ThreadStop()
        {
            Thread m_thrad = new Thread(new ParameterizedThreadStart(ThreadProcWithPro));//创建一个有参数的线程
            m_thrad = new Thread(ThreadProcWithPro);
            m_thrad.Start("今天是2023年");
            m_thrad.Join();//通过添加异常停止
        }




        /// 
        /// 一个可以被执行的方法,没有参数
        /// 
        private static void ThreadProc()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("你好,我的朋友");
                Thread.Sleep(0);
            }
        }

        /// 
        /// 一个可以被执行的方法,有参数
        /// 
        /// object类型的参数
        private static void ThreadProcWithPro(object strpar)
        {
            Console.WriteLine("传递的参数是:" + (string)strpar);
        }

        //用于演示两个线程之间全局变量是共享的
        public static int number = 0;
        private static void Func1()
        {
            for (; number < 10; number++)
            {
                if (number == 4)
                {
                    Thread.Sleep(10);
                }
                Console.WriteLine($"当前是线程1, number={number}");
            }
        }
        private static void Func2()
        {
            for (; number < 10; number++)
            {
                if (number == 5)
                {
                    Thread.Sleep(10);
                }
                Console.WriteLine($"当前是线程2, number={number}");
            }
        }

        //线程的锁,两个线程中如果有lock必须要等到当前线程执行完毕之后才能进行下一个
        private static object locktokenA = new object();//锁必须是引用类型
        private static void ThreadLine1()
        {
            lock (locktokenA)
            {
                for (; number < 10; number++)
                {
                    if (number == 5)
                    {
                        Thread.Sleep(10);
                    }
                    Console.WriteLine($"当前是线程1, number={number}");
                }
            }
        }
        private static void ThreadLine2()
        {
            lock (locktokenA)
            {
                for (; number < 15; number++)
                {
                    if (number == 7)
                    {
                        Thread.Sleep(10);
                    }
                    Console.WriteLine($"当前是线程2, number={number}");
                }
            }
        }

        //使用Monitor锁来控制多线程
        private static void ThreadLine4()
        {
            Monitor.Enter(locktokenA);

            for (; number < 10; number++)
            {
                if (number == 5)
                {
                    Thread.Sleep(10);
                }
                Console.WriteLine($"当前是线程1, number={number}");
            }
            Monitor.Exit(locktokenA);
        }
        private static void ThreadLine5()
        {
            Monitor.Enter(locktokenA);
            for (; number < 15; number++)
            {
                if (number == 7)
                {
                    Thread.Sleep(10);
                }
                Console.WriteLine($"当前是线程2, number={number}");
            }
            Monitor.Exit(locktokenA);

        }
    }
}

你可能感兴趣的:(#,C#,c#,学习,开发语言)