线程系列01,前台线程,后台线程,线程同步_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 线程系列01,前台线程,后台线程,线程同步

线程系列01,前台线程,后台线程,线程同步

 2014/9/18 18:14:02  Darren Ji  程序员俱乐部  我要评论(0)
  • 摘要:在控制台应用程序集中,Main方法开始的是一个线程。如果要再创建线程,需要用到System.Threading这个命名空间。□创建第一个线程usingSystem;usingSystem.Threading;namespaceConsoleApplication4{classProgram{staticvoidMain(string[]args){varthread=newThread(DoSth);thread.Start();}staticvoidDoSth(){Console
  • 标签:线程 同步

在控制台应用程序集中,Main方法开始的是一个线程。如果要再创建线程,需要用到System.Threading这个命名空间。

 

□ 创建第一个线程

monospace; width: 100%; margin: 0em; background-color: #f0f0f0">using System;
using System.Threading;
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            var thread = new Thread(DoSth);
            thread.Start();
        }
        static void DoSth()
        {
            Console.WriteLine("我来自另外一个线程");
        }
    }
}

 

□ 前台线程和后台线程

新建的线程在默认情况下是前台线程,可以通过把IsBackground属性设置为true,把线程定义为后台线程,一旦定义成后台线程,只要前台线程结束,无论后台线程是否结束,应用程序进程结束。

using System;
using System.Threading;
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            var thread = new Thread(DoSth);
            thread.IsBackground = true;
            thread.Start(1);
            Console.WriteLine("离开主线程");
        }
        static void DoSth(object threadId)
        {
            Console.WriteLine("我来自另外一个线程" + threadId);
        }
    }
}

○ ManagedThreadId属性,托管线程Id,在进程内唯一,与操作系统的线程Id不是一回事。
○ Start方法可以带参数,参数将被传递到线程方法
○ IsBackground属性,设置线程是否为后台线程

 

□ 线程同步

※ 线程不同步的问题

假设主程序中有一个静态变量,在主程序的方法内无限循环,每次让该静态变量自增1。

如果把该方法交给一个线程。

    class Program
    {
        private static int count = 0;
        static void Main(string[] args)
        {
            var t1 = new Thread(AddCount);
            t1.Start();
        }
        static void AddCount()
        {
            while (true)
            {
                int temp = count;
                Thread.Sleep(1000);
                count = temp + 1;
                Console.WriteLine("我的托管线程ID为:" + Thread.CurrentThread.ManagedThreadId + " 目前count的值为:" + count);
                Thread.Sleep(1000);
            }
        }
    }

运行良好,显示的count值是连续递增1。

 

如果把该方法交给2个线程。

    class Program
    {
        private static int count = 0;
        static void Main(string[] args)
        {
            var t1 = new Thread(AddCount);
            var t2 = new Thread(AddCount);
            t1.Start();
            t2.Start();
        }
        ......
    }

我们发现,count的值不是递增。也就是说,count的值没有做到同步。

1

→进入线程1,temp=0,线程1开始sleep
→进入线程2,temp=0,线程2开始sleep
→线程1"醒来",让count=1,显示count值为1,又sleep
→线程2"醒来",temp还是为0,所以count还是为1,显示count值为1,又sleep
→如此循环
这里的问题是:本想让count一直递增,但线程1和线程2没有适时同步。如何解决呢?

 

※ 让线程同步

使用lock语句块,可以让2个线程同步,让每次只有一个线程进入程序执行的某个部分。

    class Program
    {
        private static int count = 0;
        static object o = new object();
        static void Main(string[] args)
        {
            var t1 = new Thread(AddCount);
            var t2 = new Thread(AddCount);
            t1.Start();
            t2.Start();
        }
        static void AddCount()
        {
            while (true)
            {
                lock (o)
                {
                    int temp = count;
                    Thread.Sleep(1000);
                    count = temp + 1;
                    Console.WriteLine("我的托管线程ID为:" + Thread.CurrentThread.ManagedThreadId + " 目前count的值为:" + count);
                }            
                Thread.Sleep(1000);
            }
        }
    }

2

 

总结:
○ 如果允许一个主线程结束,其它线程不管执行情况如何都结束,就把其它线程设置为后台线程。
○ lock语句块能保证线程同步

 

 

 

发表评论
用户名: 匿名