我们先不要用专业的角度来看多线程。
先来回忆一下,现实生活中,自己曾经一个人做的事,和多个人同时做的事。
假如现在某百货商场做一个抢购活动,限时限量的。那么就意味着你抢得越多就越占便宜,至少可以这样去理解。
那么如果你一个人去抢的话,你只有两只手,抢得再利害也只有那么一点,在同等时间的情况下,你的机会会很少的,这也就是我们经常谈到的“效率”二字。
一个人的效率再高,终究是一个人。
但是你约上亲朋好友,一起来抢,那么你们这个团队的人,最后抢到的会最多的。
虽然你会觉得大家平分后可能还是多不了多少,但是你要从另一方面去考虑。
至少我们这一个团队的总量比别人多,还有就是大家一起协同作战,你会觉得开心,效率自然会上去。
那么按照总量来看,你一个人会花更多的时间去做这件事,而人数多的情况下,大家相对花的时间就更少。
这就是多线程的优势,所以初步的对多线程理解,可以看作是,同时做多件事情,而不是平常我们所想的那样,一件一件的事情堆着,逐个处理。
有的人就会说,多线程哪有你说的这么简单啊?
是的,它确实不简单,但是你如果把所有的问题都看作很复杂的话,等到世界末日那天,你还在想这个问题如何解决呢?
俗话说:大事化小,小事化了。就是告诉你,大问题是由很多小问题组成的,解决一个小问题少一个,迟早会解决掉所有的问题的。
好了,上面已经让大家了解到,多线程的基本特征:并发,同时进行多个事情。
下面再来了解一下另一个现象。
现在有3件事情,一件是去市里买台电视机,一件事情是去市场买点菜,一件事情是去打扫卫生。
这3件事情同时有3个人去做,但是他们由于事情的复杂度不一样,路程不一样,所以回来的时间不一样。
但是安排的人并不是坐在这里等,因为做完了他们会来报告的。
所以这里就有一个现象:异步。
所谓异步,就是指调用者不用等待这件事情的完成,而只是让它开始而已。
通俗的解释就是,安排下去就行了,而不是等到事情的完成,这样不会浪费安排者的时间。
多线程还有一个经常遇到的用法,就是同步。
有时候虽然是安排了一些人去做事情,但是还有一种特殊情况,就是需要同步一些数据。
还是拿刚才那3件事情来举例,不过这个例子不太恰当,仅作举例参考用,实际开发的时候是有类似这样的问题,但现实一般不会有的。
假如他们3个人完成任务后,都要去柜台登记一下,而登记的过程是这样的,先从打印机那里打印一张纸,然后填写自己的名字并提交给秘书,
这张纸会在上面有一个数字,这个数字是表示你是第几个回来的。
那么按照我们平常的理解,按一下打印,上面的数字会加1对吧。但是假如有这样一种情况,就是两个人同时回来的时候,并且同时按下了打印(假设按了两下),
那么这个时候两个人得到的数字可能是一样的。
所以这个时候程序上需要处理一个先后顺序的问题。
在多线程中这个叫锁,锁住一个对象,当这个对象被别的线程锁住后,其它的人只能在后面等,直到前面的人用完。这也就是我们常见到的排队。
总结上面所说,多线程有并发、异步的特性,有同步处理的需求。
什么情况下用多线程?
1.不需要过问它什么时候完成,以及不想让主程序卡住时,就用一个线程,让它慢慢的去执行就行了
2.有很多事情需要同时进行
3.特别需要效率的时候,比如多线程同时读取数据,或下载文件
多线程有什么禁忌?
1.不是线程越多越好,一般建议是CPU核数的2倍为佳,但是也可以多一些;系统的多线程总数是有限的,不要无修止的开新线程,不然系统资源会很快没有的
2.多个线程之间需要共用数据的时候,要注意同步的问题(加锁),经常会死锁,还有不必要的锁
3.在WEB服务器比如ASP.NET中用多线程有时会异常,原因是你在虚拟主机上面使用,而服务端没有给你过大的资源导致无法分配
4.在桌面程序(winform)中使用多线程时,子线程不要直接操作主线程的控件,不然会莫名的让程序就退出了
文章的结尾,我介绍一下队列。
队列就跟我们排队买票一样,这是方便管理人员。在程序中也是方便管理线程。
正在排队的人就是等待要做的事情,服务窗口就是线程。
所以队列就是一个管理器,它管理同时进行的线程数,以免线程过多,导致效率低下,甚至系统崩溃。
它的主要用处就是跟售票窗口一样,当一个人办完手续后,这个人就走了,就意味着有一个窗口处于空闲状态,所以这个时候后面排队的可以去一个人继续办理。
那么多线程也一样,当然不需要每个窗口都排队,都排在一个列表里面,当某个线程完成时,必须想办法通知队列,说我已经完成了。这个时候队列就知道已经少了一个线程在做事了,就会开一个新的线程去做下一件事情,这样让同时进行的线程数总是维持在一个特定的数内。