在控制台应用程序集中,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,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);}}}
总结:
○ 如果允许一个主线程结束,其它线程不管执行情况如何都结束,就把其它线程设置为后台线程。
○ lock语句块能保证线程同步