一、什么是进程?
简单理解,在多任务系统中,每个独立运行的程序就是一个进程,也可以理解为当前正在运行的每个程序都是一个进程。我们现在使用的操作系统大都是多任务系统的,如:Windows、Linux、Mac OS X、Unix等。因为单个CPU在同一时刻只能执行一个程序,这是铁律。但在系统中单个CPU又怎么能同时执行多个程序呢?实际情况这是由操作系统负责对CPU资源进行调度和分配管理的,虽然单个CPU在某一时刻只能做一件事,但是它以非常小的时间间隔切换来执行多个程序,人用弱眼根本无法察觉CPU在来回交替执行多个程序,所以给人以在同一时刻同时执行多个程序的感觉。如果我们同时打开两个记事本程序A和B,这就是两个不同的进程,A编辑的文稿不会影响到B。因为每个进程都有独立的代码和数据存储空间,操作的都是自己空间的数据,所以互不影响。
二、什么是线程?
一个进程中可以包含一个或多个线程,一个线程就是程序内部的一条执行线索。在单线程中,当程序启动时,就自动产生了一个线程,这个线程称为主线程。主函数main就是在这个线程上运行的,然后主函数按照程序代码的调用顺序依次往下执行。在这种情况下,当主函数调用了子函数,主函数必须等待子函数返回以后才能继续往下执行,不能实现两段代码交替执行的效果。如果要在一个程序中交替执行多段代码,就需要产生多个线程,并指定每个线程上所要运行的程序代码,这就是多线程。在Java中创建多线程有两种方法:继承java.lang.Thread类和实现Runnable接口,并调用Thread类的start方法来启动线程。
三、进程与线程场景分析与理解
1> 计算机的核心是CPU,承担了所有的计算任务。它就好比一座工厂,时刻都在运行。为工厂中的每个部件提供疏通与处理的服务。
2> 假设这座工厂的电力有限,一次只能供给一个车间使用,也就是说一个车间开工的时候,其它车间都必须停工。背后的意思就是说一个CPU同一时间只能执行一个任务(进程)。
3> 进程就好比工厂的车间,任一时刻都只有一个车间在开工生产,其它车间都处于停工状态。背后的意思就是说,CPU在任一时刻总是只能运行单个进程,其它进程都处于非活动状态。
4> 一个车间里可以有很多个工人,它们协同完成一个任务。比如一个手机生产车间,张三负责主板的安装与调试,李四负责显示屏的测试与加工,王五负责手机零件的组装等。线程就好比这车间里的工人,一个进程包含了多个线程,它们各自负责完成自己的任务。
5> 车间里的空间是工人们共享的,比如车间里的许多房间(如:加工房、生产房、组装房等),这些车间里的每个房间,工人们都是可以随意走动、进出的。这就象征者一个进程的内存空间是共享的,该进程中的所有线程都可以使用这片内存空间。
6> 可是车间里每间房间的大小是不同的。有些房间最多只能容纳1个人,比如厕所,里面有人的时候,你就不能再进去了,需要等里面的人出来了你才能进去。也就是说当一个线程在使用某块共享内存的时候,其它线程必须等待它使用结束之后,其它线程才能使用这块内存。
7> 一个访止他人进入的简单办法,就是进入厕所之后,在外面挂一把锁。先到的人进入厕所后锁上门,后到的人看到厕所上锁了,就在门口排队,等锁打开了再进去。这就是"互斥锁"(mutex),防止多个线程同时读写某一块内存区域中的数据。在Java中使用synchronized关键字实现多个线程之间的互斥。
8> 还有些房间,可以同时容纳N个人,比如说厨房。如果人数大于N,多出来的人数只能在外面等着,等待其它人出来之后才能进去。这就好比某些共享内存区域,只供固定数目的线程访问。
这时的解决方式就是在门外挂N把锁,进去的人就取一把锁,出来时把锁挂回原处。后到的人发现钥匙架空了,就知道在门外排队等着了。这种做法叫做**“信号量(Semaphore)**”,用来保证多个线程不会互相冲突。