小陈在完成一段代码后进行了测试,发现代码的运行效率无法满足需求,在提高程序的执行效率同时不影响功能的前提下,想到了一个还不错的解决方案——多线程。接下小陈老师会以简单直白的方式让大家更加容易理解什么是多线程。
讲到“线程”这个词不得不先和大家说下它的另外两兄弟“程序”和“进程”,那么它们之间又是什么关系呢?
程序:当我们打开电脑或手机上的软件,比如浏览器、游戏或文字处理器,其实都是程序。程序就是一系列的指令,告诉计算机要做什么事情。就像一本菜谱教会你怎么做菜一样,程序告诉计算机怎么完成各种任务。
进程:进程是计算机中正在运行的程序的一个实例。就像你打开了一个游戏,或者同时运行了几个应用程序,每个运行中的程序都是一个进程。每个进程都有它自己独立的运行空间,就像每个人在自己的房间里做自己的事情一样。
线程:线程是进程中的小单位,它是一个执行任务的工作单元。就像一本书中的每一页,每个线程负责完成进程中的一部分工作。不同的线程可以同时在一个进程中工作,就像多个人在一个房间里同时做不同的事情。
回到我们文章的开头,我们为什么要使用多线程呢?首先是多线程可以提高我们程序的效率,举一个实际的生活案例,老师让小明同学在一个小时之内打扫完二十间教室,但是实际情况,小明一个小时只能打扫五间教室,如果按照这样的话需要四小时才能完成,为了完成老师的任务在一个小时只能完成,小明可以邀请小红、小军、小芳四个人一起打扫,这样四个人同时干活,在一个小时内完成了任务,原本用4个小时完成的任务现在只需要1个小时就完成了,如果把每位同学看做一个线程,多个同学即多线程可以提高程序的效率(如图1)。
那么同学可能会有新问题了,多线程的应用场景是什么呢?一般来说线程和线程之间比较独立,互不影响,比如一个线程任务是收取小王的邮件,另外一个线程的任务是收取小芳的邮件,这就属于互不影响。
当然还有情况就是并行的任务之间没有继承或因果关系,比如小明一个人打扫需要四小时,如果四个人打扫只需要一个小时,明显效率提升了,但如果小明的工作成果是其他人的工作原材料,那么其他线程就只能在旁边干瞪眼了,这也是程序运行时死机的原因之一——后续线程等不到前置线程反馈的结果。
下面我就通过Java代码展示简单的单线程和多线程的运用,以吃饭和喝酒举例,正常单线程情况下就是顺序执行:开始吃饭,结束吃饭,开始喝酒,结束喝酒。顺序执行下来,在每一步中间我还等待了一秒钟(图2)。
如果我想边吃饭边喝酒的话就需要通过多线程来实现了。多线程的实现方式和具体实现方法有很多种,本例我采用了继承Thread类,重写run方法的形式完成多线程的执行。我们也可以通过实现Runable接口,重写run方法,这一样可以完成任务(图3)。通过的代码的运行我们不难发现原本先吃饭后喝酒就变成了边吃饭边喝酒,你能体会到多线程的好处吗?
多线程相比单线程来说有很大的优势,多线程允许程序在同一时间执行多个任务,利用多核处理器的性能,实现并行处理,从而加快程序的执行速度。这在处理大规模计算密集型任务时特别有效。
在单线程程序中,如果有一个耗时的任务在执行,会导致整个程序被阻塞,用户体验较差。而多线程允许将耗时任务放入后台线程执行,主线程可以保持响应,不会被阻塞,从而提高系统的响应性和用户体验。