01.线程

线程

操作系统中的多任务即在同一时刻运行多个程序的能力。操作系统将 CPU 的时间片分配给每一个进程,给人并行处理的感觉。多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为一个线程。可以同时运行一个以上线程的程序称为是多线程程序。

多进程与多线程本质的区别在于每个进程拥有自己的一整套变量,而线程则共享数据。共享变量使线程之间的通信比进程之间的通信更有效、更容易。在有些操作系统中,与进程相比,线程更“轻量级”,创建、撤销一个线程比启动新进程的开销要小得多。

Java 线程与操作系统线程

Java 线程在 JDK1.2 之前,是基于称为绿色线程(Green Threads)的用户线程实现的,而到了 JDK1.2 及以后,JVM 选择了更加稳健且方便使用的操作系统原生的线程模型,通过系统调用,将程序的线程交给了操作系统内核进行调度。因此,在目前的 JDK 版本中,操作系统支持怎样的线程模型,在很大程度上决定了 Java 虚拟机的线程是怎样映射的,这点在不同的平台上没有办法达成一致,虚拟机规范中也并未限定 Java 线程需要使用哪种线程模型来实现。线程模型只对线程的并发规模和操作成本产生影响,对 Java 程序的编码和运行过程来说,这些差异都是透明的。

对于 Sun JDK 来说,它的 Windows 版与 Linux 版都是使用一对一的线程模型实现的,一条 Java 线程就映射到一条轻量级进程之中,因为 Windows 和 Linux 系统提供的线程模型就是一对一的。也就是说,现在的 Java 中线程的本质,其实就是操作系统中的线程,Linux 下是基于 pthread 库实现的轻量级进程,Windows 下是原生的系统 Win32 API 提供系统调用从而实现多线程。

Java 线程状态的变化

在现在的操作系统中,因为线程依旧被视为轻量级进程,所以操作系统中线程的状态实际上和进程状态是一致的模型。从实际意义上来讲,操作系统中的线程除去 new 和 terminated 状态,一个线程真实存在的状态,只有:

  • ready:表示线程已经被创建,正在等待系统调度分配 CPU 使用权。
  • running:表示线程获得了 CPU 使用权,正在进行运算。
  • waiting:表示线程等待(或者说挂起),让出 CPU 资源给其他线程使用。

对于 Java 中的线程状态:无论是 Timed Waiting,Waiting 还是 Blocked,对应的都是操作系统线程的 waiting(等待)状态。而 Runnable 状态,则对应了操作系统中的 ready 和 running 状态。Java 线程和操作系统线程,实际上同根同源,但又相差甚远。