一 概述
Java内置了对多线程编程的支持,使得可以通过充分利用cpu来开发出高效率的程序。一条线程是指进程中一个单一顺序的控制流,一个进程可以并发使用多个线程,每条线程则并行执行各自的任务。
二 回顾进程
一个进程包括由操作系统分配的内存空间,含有一个或多个线程,一个线程必须是某个进程的一部分而无法独立存在,而进程会一直运行,直到所有的非守护线程都与运行结束才能结束。
三 一个线程的生命周期
线程新建状态:使用java中的new关键字和Thread类或者其子类实例化出一个线程对象后,该线程对象会处于新建状态,并且保持这个状态直到调用线程的start()方法
public class Thread implements Runnable { public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
}
就绪状态:当线程对象调用了start()方法之后,该线程就进入了就绪状态,就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
运行状态:如果就绪状态的线程获取CPU资源,就可以执行run()方法,此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态,就绪状态和死亡状态。
/* What will be run. */
private Runnable target;
//Thread重写了Runnable中的run方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
阻塞状态:如果一个线程执行了sleep(睡眠),suspend(挂起)等方法,释放当前所占用的资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或者获得设备资源之后可以重新进入就绪状态。
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis);
}
//Java1.8中该方法提示弃用
@Deprecated
public final void suspend() {
checkAccess();
suspend0();
}
阻塞状态的几种情况:
等待阻塞:运行状态中的线程运行wait()方法时,是的该线程进入等待阻塞状态。
[Object类中]
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
同步阻塞:线程由于同步锁被其它线程占用在获取synchronized同步锁失败。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡状态: 一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。