操作系统将 CPU 时间片分配给每一个进程,给人并行处理的感觉。
并且,一个进程可以运行多个线程(同一时间只能运行一个线程)。同时运行一个以上的线程称为多线程(multitireaded)。
多线程与多进程最本质的差别在于:每个进程拥有自己的一整套变量,而线程则共享数据。当然,在线程中交换数据非常复杂,很容易造成误修改。但是正是因为共享数据,使得线程之间的通信更有效、更容易。另外,线程的创建、撤销开销都没有启动新进程大。
对于大多数 Java 程序来说,我们说多任务,实际上是说如何使用多线程实现多任务。
当 Java 程序启动的时候,实际上是启动了一个 JVM 进程,然后,JVM 启动主线程来执行 main()
方法。在 main()
方法中,我们又可以启动其他线程。
单核 CPU 一个时间片只能运行一个进程。但是因为它切换速度很快,所以我们感受不到,就造成了一种多进程的假象。
当进程 A 执行完一个时间片,但是还未执行完,为了方便下次接着执行,要保存刚刚执行完的这些数据信息,叫做「保存现场」。下次抢到资源,先「恢复现场」,在继续执行。
这样循环往复。直到该进程执行完毕。
这样反复的保存、恢复。都是格外的开销,会让程序执行变慢。
线程隶属于进程,一个进程可以拥有多个线程。与进程的区别就是,线程不需要保存、恢复现场。这就是 NIO 模型的思路,与 BIO 相对。
每个线程都有自己的 栈,记录该线程里的方法相互调用的关系。一个进程里的所有线程是共用 堆 的。
不同的进程之间是不可以互相访问内存的,每个进程都有自己的内存空间(memeory space),也叫虚拟内存(virtual memory)。通过这个虚拟内存,每个进程都感觉自己拥有了整个内存空间。
多线程 VS 多进程
因为进程之间的独立性,进程 A 出现问题不会影响到进程 B。
虽然线程之间也相互独立,但是他们依赖于同一个进程,使用同一个堆,如果某个线程 out of memory
(内存不足),那么这个进程里所有的线程都完了。
所以多进程能够提高系统的容错性 fault tolerance
,而多线程最大的好处就是线程间的通信非常方便。