代码改变世界

NET多线程探索-NET线程基础知识点

2012-03-19 13:40  海不是蓝  阅读(691)  评论(0编辑  收藏  举报

前台线程和后台线程


前台线程:当应用程序结束的时候,前台线程如果没有完成任务,那么前台线程就不会结束。除非你强行结束应用程序进程中所有前台线程。前台线程适合必须执行完的任务。
后台线程:当应用程序结束的时候后台线程会被CLR强行结束,不会抛出异常。示例:

static void Main(string[] args)
{
    Thread t = new Thread(Test);
    t.IsBackground = true;
    //这里线程是后台线程,应用程序马上结束
    //假如是前台线程,大约5秒以后结束
    t.Start();
    Console.WriteLine("A");
}
static void Test()
{
    Thread.Sleep(5 * 1000);
    Console.WriteLine("B");
}

 

判断线程是否结束

 

public bool IsAlive { get; }
public void Join();

 

static void Main(string[] args)
{
    Thread A = new Thread(() => { Thread.Sleep(2 * 1000); });
    Thread B = new Thread(() => { Thread.Sleep(3 * 1000); });
    A.Start();
    B.Start();
    while (A.IsAlive)
    {
        Console.WriteLine("线程A正在执行...");
        Thread.Sleep(500);
    }
    Console.WriteLine("线程A执行完毕...");
    //这个是阻塞方法,直到线程B完成才能执行后面的代码
    B.Join();
    Console.WriteLine("线程B执行完毕...");
    Console.Read();
}

 

为线程传递参数

 

public delegate void ParameterizedThreadStart(object obj);
[SecuritySafeCritical]
public Thread(ParameterizedThreadStart start);

 

static void Main(string[] args)
       {
           Thread A = new Thread((object str) =>
           {
               Thread.Sleep(1 * 1000);
               Console.WriteLine(str);
           });
           A.Start("A Thread...");
           A.Join();//阻塞程序直到A线程执行完毕

           Thread B = new Thread(new ParameterizedThreadStart((object str) =>
           {
               Thread.Sleep(1 * 1000);
               Console.WriteLine(str);
           }));
           B.Start("B Thread...");
           B.Join();

           Thread C = new Thread(new ParameterizedThreadStart(Test));
           C.Start("C Thread...");
           Console.Read();
       }
       static void Test(object str)
       {
           Thread.Sleep(1 * 1000);
           Console.WriteLine(str);
       }

 

线程优先等级


优先等级高的线程占用更多的CUP时间。
但是当优先等级高的线程正在等待一些资源的时候,优先等级低的线程可以运行。

public class MyThread
    {
        //执行计数
        public Int32 Count;
        //执行开关
        public static bool Stop;
        //执行线程
        public Thread t;

        public MyThread(string ThreadName)
        {
            //设置开关
            Stop = false;
            //设置线程方法
            t = new Thread(new ThreadStart(() =>
            {
                while (!Stop && Count < 10000000)
                {
                    Count++;
                }
                Stop = true;
                Console.WriteLine("{0}线程结束...", t.Name);
            }));
            //设置线程名字
            t.Name = ThreadName;
        }
    }

 

static void Main(string[] args)
{
    MyThread A = new MyThread("Hige A");
    MyThread B = new MyThread("Low B");

    A.t.Priority = ThreadPriority.Highest;
    B.t.Priority = ThreadPriority.Lowest;

    A.t.Start();
    B.t.Start();

    A.t.Join();
    B.t.Join();

    Console.WriteLine("A线程计数{0}", A.Count);
    Console.WriteLine("B线程计数{0}", B.Count);
    Console.Read();
}

图片1

 

线程池


注意几点: 1.托管线程池中的线程都是后台线程, 2.当需求比较少时,线程池线程的实际数量可以低于这些最小值。

线程池的优点:创建线程和销毁线程都是需要消耗比较多的系统资源,而线程池始终维护着一个线程列表,当线程处于空闲的时候只是休眠,

一旦有任务进来就会被唤醒执行任务。

static void Main(string[] args)
{
    ThreadPool.QueueUserWorkItem((object str) =>
    {
        Thread.Sleep(1 * 1000);
        Console.WriteLine(str);
    }, "Hello");

    int max, min, io;
    ThreadPool.GetMaxThreads(out max, out io);
    Console.WriteLine("线程池中辅助线程的最大数目:{0},\n线程池中异步 I/O 线程的最大数目{1}", max, io);
    ThreadPool.GetMinThreads(out min, out io);
    Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0},\n线程池根据需要创建的最少数量的异步 I/O 线程{1}", min, io);
    Console.Read();
}

线程池适合一些简单的任务,如果对任务线程需要比较全的控制权限,那么就自己单独声明线程。

 

作者:海不是蓝
博客:hailan2012
邮箱:hailan2012@sina.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。