线程
线程是CPU调度的基本单位,使用线程可以代码抽离出来,简化编码 ,实现并发执行。
- 前台线程
前台线程为默认线程,前台线程的特点是应用程序退出时必须等待所有的前台线程完成。 - 后台线程
后台线程即线程属性IsBackground=false 在应用程序退出时只要前台线程都结束,不考虑后台线程是否结束。
线程池
-
线程池的优势
- 减少在创建和销毁线程上所花的时间以及系统资源的开销
- 如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”。
static void Main(string[] args)
{ ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod1), new object()); //参数可选 Console.ReadKey(); } public static void ThreadMethod1(object val) { for (int i = 0; i <= 500000000; i++) { if (i % 1000000 == 0) { Console.Write(Thread.CurrentThread.Name); } } }
线程同步
线程安全是指在当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。
线程锁
使用关键字Lock 给方法加一个线程锁 每次只能操作一个线程 必须等待线程结束完再执行,可以解决线程同步带来的问题
static void Main(string[] args)
{
Program pro = new Program();
Thread threadA = new Thread(pro.ThreadMethod); //执行的必须是无返回值的方法
threadA.Name = "王文建";
Thread threadB = new Thread(pro.ThreadMethod); //执行的必须是无返回值的方法
threadB.Name = "生旭鹏";
threadA.Start();
threadB.Start();
Console.ReadKey();
}
public void ThreadMethod(object parameter)
{
lock (this) //添加lock关键字
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
Thread.Sleep(300);
}
}
}
死锁
在应用程序开发的过程当中会出现出现一个 “你等我,我等你” 的这种情况,会造成线程一直出现等待的过程。
线程的相关操作
-
Abort()方法
Abort()方法用来终止线程,调用此方法强制停止正在执行的线程,它会抛出一个ThreadAbortException异常从而导致目标线程的终止。下面代码演示:static void Main(string[] args) { Thread thread = new Thread(ThreadMethod); //执行的必须是无返回值的方法 thread.Name = "小A"; thread.Start(); Console.ReadKey(); } public static void ThreadMethod(object parameter) { try { Console.WriteLine("我是:{0},我要终止了", Thread.CurrentThread.Name); //开始终止线程 Thread.CurrentThread.Abort(); } catch(ThreadAbortException ex) { Console.WriteLine("我是:{0},我又恢复了", Thread.CurrentThread.Name);//恢复被终止的线程 Thread.ResetAbort(); } for (int i = 0; i < 10; i++) { Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i); } }
-
Sleep()方法
Sleep()方法调已阻塞线程,是当前线程进入休眠状态,在休眠过程中占用系统内存但是不占用系统时间,当休眠期过后,继续执行,声明如下:
public static void Sleep(TimeSpan timeout); //时间段
public static void Sleep(int millisecondsTimeout); //毫秒数
static void Main(string[] args)
{
Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法
threadA.Name = "小A";
threadA.Start();
Console.ReadKey();
}
public static void ThreadMethod(object parameter)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
Thread.Sleep(300); //休眠300毫秒
}
}
-
join()方法
Join方法主要是用来阻塞调用线程,直到某个线程终止或经过了指定时间为止。官方的解释比较乏味,通俗的说就是创建一个子线程,给它加了这个方法,其它线程就会暂停执行,直到这个线程执行完为止才去执行(包括主线程)。 其它的线程都让开 自己优先处理,处理完了再等其它线程处理。它的方法声明如下:
public void Join(); public bool Join(int millisecondsTimeout); //毫秒数 public bool Join(TimeSpan timeout); //时间段