线程的状态转换

通过源码分析,线程的状态大部分都是用虚拟机设置的,只有在线程新建而未启动的时候,线程的状态值为0,处于State.NEW状态。
Java线程状态.png

  • NEW
    新建状态,线程对象新建时的状态。
  • RUNNABLE
    就绪状态,调用了线程的start()方法后,随时等待CPU调度。
  • BLOCKED
    阻塞状态,等待synchronized 锁。
  • WAITING
    当调用了Object.wait,Thread.join,LockSupport.park方法后(没有超时设定),挂起当前线程。
  • TIMED_WAITING
    调用了Thread.sleep,Object.wait,Thread.join,LockSupport.parkUntil,LockSupport.parkNanos有超时设定的方法,挂起当前线程一段时间。
  • TERMINATED
    线程执行结束。

常用方法

currentThread()

获取当前线程的引用,静态方法。

1
2
3
4
5
6
7
/**
* Returns a reference to the currently executing thread object.
* 返回对当前正在执行的线程对象的引用。
* @return the currently executing thread.
*/
public static native Thread currentThread();

sleep(long millis)

睡眠一段时间,让出CPU,线程处于TIMED_WAITING状态。即不参与CPU竞争,即使是sleep(0)。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds, subject to
* the precision and accuracy of system timers and schedulers. The thread
* does not lose ownership of any monitors.
*
* @param millis the length of time to sleep in milliseconds
* @throws IllegalArgumentException if the value of {@code millis} is negative
* @throws InterruptedException if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public static native void sleep(long millis) throws InterruptedException;
yield()

线程调用yield()方法后,线程还是属于RUNNANLE状态,也就是会重新竞争CPU,可能前脚刚让出CPU,后脚就抢回来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* A hint to the scheduler that the current thread is willing to yield
* its current use of a processor. The scheduler is free to ignore this
* hint.
*
* <p> Yield is a heuristic attempt to improve relative progression
* between threads that would otherwise over-utilise a CPU. Its use
* should be combined with detailed profiling and benchmarking to
* ensure that it actually has the desired effect.
*
* <p> It is rarely appropriate to use this method. It may be useful
* for debugging or testing purposes, where it may help to reproduce
* bugs due to race conditions. It may also be useful when designing
* concurrency control constructs such as the ones in the
* {@link java.util.concurrent.locks} package.
*/
public static native void yield();
isAlive()

判断虚拟机新创建的线程是否存活。

1
2
3
4
5
6
7
8
/**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.
*
* @return <code>true</code> if this thread is alive;
* <code>false</code> otherwise.
*/
public final native boolean isAlive();

#####join(long millis)

该方法等待this thread终止,最多等指定的时间,如果指定时间为0,则一直等。即线程可能处于WAITING或TIMED_WAITING状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*
* @param millis the time to wait in milliseconds
* @throws IllegalArgumentException if the value of {@code millis} is negative
* @throws InterruptedException if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}

if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

以前分析JAVA线程的时候,都会有个running状态,在源码中,RUNNABLE状态即包括了准备被CPU调用状态和正在执行状态。