20240208 多线程相关的实操

一、Thread进程;;主要是先声明 ,声明的时候可以根据需要传递参数或者不传递,以及指定栈大小;生成的进程,要start后才启动,启动后,可以查询状态(ThreadState 属性)

            通过一个委托进行实例化一个函数public delegate void ParameterizedThreadStart(object obj);
            Thread threadName1 = new Thread(new ParameterizedThreadStart(myOneArgFun));
            MyArg arg = new MyArg("name",20);
            threadName1.IsBackground = false;//是否后台进程
            threadName1.Start(arg);  //启动了一个带参数的进程
            
            //threadName1.Join();//等待进程,不会再继续
            Console.WriteLine("stop main");
            //Console.ReadLine();
            //threadName1.Join();//等待进程,不会再继续执行后面的内容
            //threadName1.Abort();//终止进程
            //Thread treadName = Thread.CurrentThread; 可以在子进程中获取自己的进程名字,方便进行操作
            //threadName1.Suspend();
            //threadName1.IsBackground = true;//是否后台进程
            //Thread threadName2 = new Thread(new ThreadStart(targNoArg));//定义一个无参数的进程
            //Thread threadName3 = new Thread(new ParameterizedThreadStart(myOneArgFun),10000);//定义一个有一个参数的进程 并指定栈的大小
            //Thread threadName4 = new Thread(new ThreadStart(targNoArg),10000);//定义一个无参数的进程并指定栈的大小
            //m默认的参数类型都是 obj格式,可以自己定义,然后自己转换
            //threadName2.Start();

也可以使用简单方法,直接定义一个参数或0参数的,根据你的函数自动调用

            Thread threadname4 = new Thread(myOneArgFun);
            Thread threadname5 = new Thread(targNoArg);

除了上述方法,传递参数的时候,还可以通过先实例化一个有属性有方法(没有参数)的类,然后定义线程的时候,使用该实例的方法,就可以直接使用该类中的其他属性

Thread threadname6 = new Thread(new ThreadStart(arg.printname));

 public class MyArg:Object {
     public MyArg(string name, int age)
     {
         this.name = name;
         this.age = age;
     }

     string name { get; set; }
     int age {  get; set; }  
     public void printname() {
         Thread.Sleep(1000);
         Console.WriteLine(name);
         Console.WriteLine(age);
         Thread.Sleep(2000);
     }
 }

2)线程池  暂时还没有使用,这里是拷贝的,后面有机会再去研究;

ThreadPool类维护一个线程的列表,提供给用户以执行不同的小任务,减少频繁创建线程的开销。ThreadPool的使用比较简单,只需调用ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallback类型的委托,线程池即从池中选择一个线程执行该任务。
链接:https://www.jianshu.com/p/36a65838fe46
 

        public static void Main()
        {
            for (int i = 0; i < 5; ++i)
                ThreadPool.QueueUserWorkItem(DoWork);

            Console.ReadKey();
        }

        public static void DoWork(Object o)
        { 
                for (int i = 0; i < 3; i++)
                    Console.WriteLine("loop:{0}, thread id: {1}", i, Thread.CurrentThread.ManagedThreadId);
        }

3)TASK这个是比较重要的,相比于Thread类,Task类为控制线程提供了更大的灵活性。Task类可以获取线程的返回值,也可以定义连续的任务——在一个任务结束结束后开启下一个任务,还可以在层次结构中安排任务,在父任务中可以创建子任务,这样就创建了一种依赖关系,如果父任务被取消,子任务也随之取消。Task类默认使用线程池中的线程,如果该任务需长期运行,应使用TaskCreationOptions.LongRunning属性告诉任务管理器创建一个新的线程,而不是使用线程池中的线程。

最简单的的任务执行,使用的lambda表达式;

           Task.Run(() => {
           
           while (true)
               {
                   Console.WriteLine("loop");
                   Thread.Sleep(100);
               }
           });


            Task t2 = new Task(() => {

                while (true)
                {
                    Console.WriteLine("loop222");
                    Thread.Sleep(100);
                }
            });
            t2.Start();

           Thread.Sleep(1000);
           Console.WriteLine("stop main");

4)多线程会涉及到资源冲突,lock有时会需要到;关键设置为 readonly 然后通过lock锁定。

        readonly object locker = new object();

        public void fun() {
            lock (locker)
            {

            }
        }
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值