• 多线程编程学习笔记-基础(二)


    接上文 多线程编程学习笔记-基础(一)

    五、终止线程 (Abort)

    1.代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading; //引入线程 
    
    namespace ThreadConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("开始");
                Thread t = new Thread(PrintNumberDely);
    
                //启动线程
                t.Start();
                Thread.Sleep(TimeSpan.FromSeconds(6));
    
                //线程终止
                t.Abort();          
    
                Console.WriteLine("线程终止");
                Console.WriteLine("启动新线程");
                t = new Thread(PrintNumber);
                t.Start();
                PrintNumber();
                Console.Read();          
    
            } 
    
            static void PrintNumber()
            {
                Console.WriteLine("第四个多线程程序开始。。。。Second:" + DateTime.Now.Second);
                for (int i = 0; i <10; i++)
                {
                    Console.WriteLine(string.Format("{0}",i));
                }
            }
    
            /// <summary>
            /// 暂停2秒的方法
            /// </summary>
            static void PrintNumberDely()
            {
                Console.WriteLine("第一个多线程终止程序开始。。。。");
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(string.Format("Second:{0} ==  {1}", DateTime.Now.Second, i));
    
                    Thread.Sleep(TimeSpan.FromSeconds(2));            
              
                }
            }
        }
    }

    2.程序执行结果如下

     

     从结果中,可以看出来,程序先启动了子线程的打印数字方法,在运行了6秒之后,调用了abort方法,终止了子线程。但是这个abort是通过注入ThreadAbortException方法,从而使用线程终止,这种方法非常危险,不建议使用。在子线程终止之后,主线程继续运行。

     

    六、检测线程状态(ThreadState)

    1.代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading; //引入线程
    
    namespace ThreadConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("开始");
                Thread t = new Thread(PrintNumberStatus);
                Thread t2 = new Thread(DoNothing);
                //启动线程
                t2.Start();
                t.Start();
                //显示线程状态
                for (int i = 0; i < 10; i++)
                {
    
                    Thread.Sleep(TimeSpan.FromMilliseconds(300));
                    Console.WriteLine(t.ThreadState.ToString());
                }
                Thread.Sleep(TimeSpan.FromSeconds(4));
                //线程终止
                t.Abort();
    
                Console.WriteLine("线程终止");
                Console.WriteLine(string.Format("t线程状态:{0}", t.ThreadState.ToString()));
                Console.WriteLine(string.Format("t2线程状态:{0}", t2.ThreadState.ToString()));
                Console.Read();
            }
     
    
            static void DoNothing()
            {
                Console.WriteLine("第五个多线程程序开始。。。。Second:" + DateTime.Now.Second);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }
    
            /// <summary>
            /// 暂停2秒的方法
            /// </summary>
            static void PrintNumberStatus()
            {
                Console.WriteLine("第五个多线程检测状态程序开始。。。。" + Thread.CurrentThread.ThreadState.ToString());
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(string.Format("Second:{0} ==  {1}", DateTime.Now.Second, i));
                    Thread.Sleep(TimeSpan.FromSeconds(2)); 
    
                }
            }
        }
    }

    2.程序执行结果如下

     

     如上图,主线程启动时定义了两个子线程,一个会被终止,另一个会运行至结束。当我们启动了线程之后,t2线程的状态就会变成Running,然后会变成WaitSleepJoin,直到运行结束,变成Stopped。另一个t线程则会打印出数字来,当我们调用了abort方法之后,则t线程的状态就变成了AbortRequested。这充分说明了同步两个线程的复杂性,请不要程序中使用abort来终止线程。

     

    七、线程优先级(Priority

    1.代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading; //引入线程
    using System.Diagnostics; 
    
    namespace ThreadConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("开始,当前线程的优先级:"+Thread.CurrentThread.Priority);
                Console.WriteLine("线程运行多核CPU上");
                //启动线程
                Run();  
                Thread.Sleep(TimeSpan.FromSeconds(2));
     
    
                //单核模拟
                Console.WriteLine("线程运行单核CPU上");     
    
                Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
                Run();
                Console.Read();
    
            }
    
     
    
            static void Run()
            {
                var demo = new ThreadRunDemo();
                Thread thread1 = new Thread(demo.CountNumber);
                thread1.Name = "ThreadOne";
                Thread thread2 = new Thread(demo.CountNumber);
                thread2.Name = "ThreadTwo";
                thread2.Priority = ThreadPriority.BelowNormal;
                Thread thread3 = new Thread(demo.CountNumber);
                thread3.Name = "ThreadThree";
     
    
                thread1.Priority = ThreadPriority.Highest;
                thread2.Priority = ThreadPriority.AboveNormal;
                thread3.Priority = ThreadPriority.Lowest; 
    
                thread1.Start();
                thread2.Start();
                thread3.Start();          
    
                Thread.Sleep(2000);
                demo.Stop();
            }
        }
    
        class ThreadRunDemo
        {
            private bool isStopped = false;
            public void Stop()
            {
                isStopped = true;
            }
    
            public void CountNumber()
            {
                long cnt = 0;
                while(!isStopped)
                {
                    cnt++;
                }
                Console.WriteLine(string.Format("线程 {0} 的优先级 {1,11} ,一共计算了 {2,13} 数字",
    Thread.CurrentThread.Name,Thread.CurrentThread.Priority.ToString(), cnt.ToString("N0"))); } } }

    2.程序执行结果如下

     

     从上图的结果中,看出来当在多核CPU上运行多线程程序时,优先级所起到的作用区别不大,以上图的结果来看,最高优先级与最低优先级之间的差别在10%左右。如果在单核CPU上运行多线程程序时,优先级的作用的特别明显,以上图的结果来看,最高优先级与最低优先级之间的差别在100倍以上。

     

    八、前台线程与后台线程

    1.代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading; //引入线程
    using System.Diagnostics; 
    
    namespace ThreadConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                Console.WriteLine("开始,前台线程与后台线程");           
    
                var fore = new ThreadBackground(10);
                var back = new ThreadBackground(20);
                Thread threadF = new Thread(fore.CountNumber);
                threadF.Name = "前台线程";
                Thread threadB = new Thread(back.CountNumber);
    
                threadB.Name = "后台线程";
                threadB.IsBackground = true;
     
    
                //启动线程
                threadF.Start();
                threadB.Start();
                //Console.Read(); 
    
            }
        }
    
        class ThreadBackground
        {
            private  int cnt ;
            public  ThreadBackground(int count)
            {
                cnt = count;
            }
    
            public void CountNumber()
            {
                for (int i = 0; i < cnt; i++)
                {
                    Thread.Sleep(500);
                    Console.WriteLine(string.Format("线程 {0} 打印 {1,11} 数字", Thread.CurrentThread.Name, i.ToString("N0")));
                }
                Console.WriteLine("{0} finished counting.",
                                Thread.CurrentThread.IsBackground ?
                                "Background Thread" : "Foreground Thread");        }
           
        }
    }
    
     

    2.程序执行结果

     

     根据上面的代码,当程序执行到如上图时,会一闪而过,退出。这是因为前台线程已经执行结束,虽然后台线程没有执行结束,但程序会自动终止后台线程。这就是前台线程与后台线程的区别,进程会等所有的前台线程执行完毕,如果此时只剩下后台线程没有执行完毕,则会直接结束工作。

     

  • 相关阅读:
    使用PHP类库PHPqrCode生成二维码
    ABAP报表中建立过滤器,并相互切换
    MM定价计算方案确定详细图解
    MIGO 屏幕增强
    SE14 激活表时提示进程正在运行
    供应商寄售
    屏蔽VA01的TA類型的銷售部門和銷售組
    屏蔽標準TCODE上的一些字段的顯示、隱藏或者強制輸入(轉)
    采购订单流程
    SAP 中如何修改透明表数据
  • 原文地址:https://www.cnblogs.com/chillsrc/p/7699076.html
Copyright © 2020-2023  润新知