进程与线程概念
在现代操作系统中,进程支持多线程。
- 进程是资源管理的最小单元,
- 线程是程序执行的最小单元。
线程作为调度和分配的基本单位,进程作为资源分配的基本单位。
一个进程的组成实体可以分为两大部分:线程集和资源集。进程中的线程是动态的对象;代表了进程指令的执行。资源,包括地址空间、打开的文件、用户信息等等,由进程内的线程共享。
多道程序设计模型
计算机采用多道程序设计模型可以显著提高CPU的利用率。
多进程与多线程
多进程:并行实体之间不共享同一个地址空间和所有可用数据。
多线程:并行实体之间共享同一个地址空间和所有可用数据。
1、线程比进程更加轻量级,线程的创建、切换等过程比进程开销小,线程的通信比进程间的通信简单。
2、进程的安全性高于线程,因为不共享。
多线程的实现方式
- 内核线程实现
- 用户线程实现
- 用户线程加轻量级进程混合实现
Java线程实现在linux和windows平台上均采用的是内核线程实现,Java线程与内核线程为一比一的对应关系,也就是说Java线程由内核直接调度。
多线程面临的挑战
- 线程通信
- 上下文切换
- 死锁
- 资源限制
- 线程安全
线程通信
多线程相当于是多个线程为了完成一件“大事”而协同工作,那这多个线程之间如何协同就是线程通信的问题了。
线程间的通信是多线程编程的基础,线程间通信方式有两种:共享内存和消息传递。Java线程间的通信机制为共享内存方式。
线程间通信就要保证通信的可靠性,确保信息的可靠传递。这就涉及到线程安全的问题。
线程安全
线程安全最核心的概念是正确性。
在操作系统中,正确性是指多个线/进程读写共享数据,最后的结果与线/进程运行的精准时序无关,亦即不存在竞争条件。
在Java中,正确性是指:某个类的行为与其规范完全一致。当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。
可以将Java线程安全按由强到弱分为5类,同时也可以看到线程安全的责任由对象本身向调用者的转移:
- 不可变
不可变对象一定是线程安全的,无论是对象的方法还是方法的调用者,都不需要再采取任何的线程安全保障措施。(final关键字的使用) - 绝对线程安全
不管运行时环境如何,调用者都不需要任何额外的同步措施。这个要求非常严格,Java API中大多数都不是绝对线程安全的类。 - 相对线程安全
保证对某个对象的单独操作是线程安全的,在调用的时候不需要做额外的同步措施。但是对于同一个对象的特定顺序的连续调用,可能需要在调用端做额外的同步手段(多为扩大同步范围)来保证调用的正确性。