线程概述
线程是现代操作系统调度的最小单元,一个进程可以创建多个线程来提高系统的吞吐量和执行效率。(进程是操作系统资源分配和调度的基本单位,它可以创建多个线程,进程可创建的线程数量和操作系统有关)
线程模型分类
- 用户级线程
用户程序实现,不依赖操作系统核心。应用提供创建、同步、调度、和管理线程的函数控制用户线程。不需要用户态和内核态相互切换,速度快。内核对ULT无感知。线程阻塞则进程(包括它的所有线程)阻塞。 - 内核级线程
系统内核管理线程(KLT),内核保证线程的状态和上下文信息。线程阻塞不会引起进程阻塞。在多处理器系统上,多线程在多处理器上并行运行。线程的创建、调度和管理是由内核完成,效率要比ULT慢,比进程操作快。
java线程创建是依赖于系统内核,通过JVM调用系统库创建内核线程。内核线程与java-Thread是1:1的映射关系。
线程状态
如下图:
Thread源码中定义了线程状态枚举
/**
* 线程状态。线程可以处于以下状态之一
* NEW:尚未启动的线程处于此状态
* RUNNABLE:在java虚拟机中执行的线程处于此状态
* BLOCKED:被阻塞等待监视器锁定的线程处于此状态
* WAITING:无限期等待另一个线程执行特定操作的线程处于此状态
* TIMED——WAITING:正在等待另一个线程执行指定时间的操作的线程处于此状态
* TERMINATED:已经退出的线程处于此状态
* 线程在给定的时间点只能处于一种状态。这些状态是虚拟机状态,不反映
* 任何操作系统线程状态。
* @since 1.5
* @see #getState
*/
public enum State {
/**
* 尚未启动的线程的线程状态
*/
NEW,
/**
* 可运行线程的线程状态
*/
RUNNABLE,
/**
* 线程的线程状态被阻塞等待监视器锁定。
* 处于阻塞状态的线程正在等待监视器锁定以在调用Object.wait之后输入同步块/方法或重新输入同步块/方法。
*/
BLOCKED,
/**
* 等待线程的线程状态。 由于调用以下方法之一,线程处于等待状态:
* Object.wait没有超时
* Thread.join没有超时
* LockSupport.park
* 处于等待状态的线程正在等待另一个线程执行特定操作。
* 例如,一个已调用线程Object.wait()的对象上正在等待另一个线程来调用Object.notify()或Object.notifyAll()该对象上。
* 调用Thread.join()线程正在等待指定的线程终止。
*/
WAITING,
/**
* 具有指定等待时间的等待线程的线程状态。 由于在指定的正等待时间内调用以下方法之一,线程处于定时等待状态:
* Thread.sleep
* Object.wait超时
* Thread.join超时
* LockSupport.parkNanos
* LockSupport.parkUntil
*/
TIMED_WAITING,
/**
* 终止线程的线程状态
*/
TERMINATED;
}
- 在线程创建对象之后进入初始NEW状态,这时候还未调用start()方法。
- 调用start()方法进入运行状态,在java多线程模型中,就绪和运行都是运行状态。
- 线程在运行状态过程中,可能有多个原因导致当前线程不继续运行,比如程序主动让线程睡眠(睡眠一定时间只有再重新执行)
、程序主动让线程等待、或者被同步块阻塞,此时就对应着time_waiting、waiting、blocked状态。 - 线程中断或者任务执行完毕周线程就会进入终止状态。
Thread构造说明
/**
* 分配一个新的Thread对象。此构造函数与Thread(null,null,gname)具有相同的效果
* 其中gname是新生成的名称。
* 自动生成的名称格式:Thread-+n
* 其中n是整数
*/
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
/**
* 分配新的Thread对象。 此构造函数与Thread (null, target, gname)具有相同的效果,
* 其中gname是新生成的名称。 自动生成的名称的格式为"Thread-"+ n ,其中n是整数。
* @param target
* 启动此线程时调用其run方法的对象。
* 如果为null,这个类run方法什么都不做
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
/**
* Creates a new Thread that inherits the given AccessControlContext.
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
init(null, target,