併發編程-Thread類源碼解析及線程狀態分析
1、常用方法 源碼解析
2、線程狀態詳細分析
構造函數源碼解析:
Thread類對外開放的 public 構造
public Thread() {
this((ThreadGroup)null, (Runnable)null, "Thread-" + nextThreadNum(), 0L);
}
public Thread(Runnable target) {
this((ThreadGroup)null, target, "Thread-" + nextThreadNum(), 0L);
}
Thread(Runnable target, AccessControlContext acc) {
this((ThreadGroup)null, target, "Thread-" + nextThreadNum(), 0L, acc, false);
}
public Thread(ThreadGroup group, Runnable target) {
this(group, target, "Thread-" + nextThreadNum(), 0L);
}
public Thread(String name) {
this((ThreadGroup)null, (Runnable)null, name, 0L);
}
public Thread(ThreadGroup group, String name) {
this(group, (Runnable)null, name, 0L);
}
public Thread(Runnable target, String name) {
this((ThreadGroup)null, target, name, 0L);
}
public Thread(ThreadGroup group, Runnable target, String name) {
this(group, target, name, 0L);
}
public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {
this(group, target, name, stackSize, (AccessControlContext)null, true);
}
/**
* @param g 指定此線程屬於線程組
* @param target runnable 對象
* @param name 線程名
* @param stackSize 最大線程棧 大小
* @param inheritThreadLocals 是否繼承 父線程的 threadlocal 屬性值
*/
public Thread(ThreadGroup group, Runnable target, String name, long stackSize, boolean inheritThreadLocals) {
this(group, target, name, stackSize, (AccessControlContext)null, inheritThreadLocals);
}
私有 構造
/**
* @param g 指定此線程屬於線程組
* @param target runnable 對象
* @param name 線程名
* @param stackSize 最大線程棧 大小
* @param acc
* @param inheritThreadLocals
*/
private Thread(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) {
this.daemon = false;
this.stillborn = false;
this.threadLocals = null;
this.inheritableThreadLocals = null;
this.blockerLock = new Object();
// 所有的線程必須有名字
if (name == null) {
throw new NullPointerException("name cannot be null");
} else {
this.name = name;
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
// 如果線程組爲 null
// 1 首先從 當前安全管理器中 獲取 線程組
if (security != null) {
g = security.getThreadGroup();
}
// 2 如果 仍沒有 線程組
// 從 當前線程(很大可能 mian 線程) 獲取 線程組
if (g == null) {
g = parent.getThreadGroup();
}
}
// 線程組校驗
g.checkAccess();
if (security != null && isCCLOverridden(this.getClass())) {
security.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
}
// 線程組 添加未開始的 線程數
g.addUnstarted();
this.group = g;
// 線程是否是守護線程 和 優先級 都有繼承性
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security != null && !isCCLOverridden(parent.getClass())) {
this.contextClassLoader = parent.contextClassLoader;
} else {
this.contextClassLoader = parent.getContextClassLoader();
}
this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext();
this.target = target;
this.setPriority(this.priority);
if (inheritThreadLocals && parent.inheritableThreadLocals != null) {
//InheritableThreadLocal主要用於子線程創建時,自動繼承父線程的ThreadLocal變量,方便必要信息的進一步傳遞。
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
this.stackSize = stackSize;
this.tid = nextThreadID();
}
}
線程默認名稱
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
線程狀態
/** Thread 類 內部 枚舉
* 線程狀態一共有 6 種
*/
public static enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
private State() {
}
}
線程狀態圖
線程實例方法源碼解析
start()
Description
Causes this thread to begin execution; the Java Virtual Machine calls the run
method of this thread.
Code
/**
*/
public synchronized void start() {
if (this.threadStatus != 0) {
throw new IllegalThreadStateException();
} else {
// 往線程組中添加 該線程
this.group.add(this);
boolean started = false;
try {
// 線程開始 是 native 方法
this.start0();
started = true;
} finally {
try {
// 如果 線程啓動失敗 從 該 線程組中 remove 掉 此線程
if (!started) {
this.group.threadStartFailed(this);
}
} catch (Throwable var8) {
}
}
}
}
private native void start0();
run()
Description
If this thread was constructed using a separate Runnable
run object, then that Runnable
object’s run
method is called; otherwise, this method does nothing and returns.
Code
/**
*/
public void run() {
// 直接調用 runnable 中的 run() 方法體的邏輯
if (this.target != null) {
this.target.run();
}
}
interrupt()
Description
Interrupts this thread.
Code
/**
* 添加 中斷標識
* interrupt() 方法只是改變中斷狀態而已,它不會中斷一個正在運行的線程
* 如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,此時調用該線程的interrupt()方
* 法,那麼該線程將拋出一個 InterruptedException中斷異常(該線程必須事先預備好處理此異常)從而提早地終結
* 被阻塞狀態
*/
public void interrupt() {
if (this != currentThread()) {
// Determines if the currently running thread has permission to modify this thread.
// 校驗 是否有權限 線程修改
this.checkAccess();
synchronized(this.blockerLock) {
Interruptible b = this.blocker;
if (b != null) {
this.interrupt0();
b.interrupt(this);
return;
}
}
}
this.interrupt0();
}
setPriority(int newPriority)
/**
* 設置線程優先級
* newPriority 越大 優先級越高
*/
public final void setPriority(int newPriority) {
// 校驗 你是否有權限 線程修改
this.checkAccess();
// 線程優先級 區間[1,10]
if (newPriority <= 10 && newPriority >= 1) {
ThreadGroup g;
if ((g = this.getThreadGroup()) != null) {
// 調整 線程優先級 最大 不超過 所在線程組的最大值(默認10 可能小於10)
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
this.setPriority0(this.priority = newPriority);
}
} else {
throw new IllegalArgumentException();
}
}
getPriority()
/**
* 獲取線程優先級
**/
public final int getPriority() {
return this.priority;
}
join()
Description
Waits for this thread to die.
Code
/**
* 讓線程進入 waiting 狀態
* 如果 millis == 0L 線程進入 waiting
* 如果 millis > 0L 線程進入 timed waiting
**/
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0L;
if (millis < 0L) {
throw new IllegalArgumentException("timeout value is negative");
} else {
if (millis == 0L) {
while(this.isAlive()) {
this.wait(0L);
}
} else {
while(this.isAlive()) {
long delay = millis - now;
if (delay <= 0L) {
break;
}
// 使用wait 方法 所以 會 釋放 cpu佔用
this.wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
// 等待這個線程死亡的時間最多是毫秒 加 納秒。
public final synchronized void join(long millis, int nanos) throws InterruptedException {
if (millis < 0L) {
throw new IllegalArgumentException("timeout value is negative");
} else if (nanos >= 0 && nanos <= 999999) {
if (nanos >= 500000 || nanos != 0 && millis == 0L) {
++millis;
}
this.join(millis);
} else {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
}
public final void join() throws InterruptedException {
this.join(0L);
}
線程static方法
sleep(long var0)
Description
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.
Code
// 線程 進入 waitting timed 狀態
// 不會釋放cpu 資源(這是和 wait 和 join 很大 區別)
public static native void sleep(long var0) throws InterruptedException;
public static void sleep(long millis, int nanos) throws InterruptedException {
if (millis < 0L) {
throw new IllegalArgumentException("timeout value is negative");
} else if (nanos >= 0 && nanos <= 999999) {
if (nanos >= 500000 || nanos != 0 && millis == 0L) {
++millis;
}
sleep(millis);
} else {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
}
yield()
Description
A hint to the scheduler that the current thread is willing to yield its current use of a processor.
Code
/**
* Java線程中的Thread.yield( )方法,譯爲線程讓步。顧名思義,就是說當一個線程使用了這個方法之後,它就會把自* 己CPU執行的時間讓掉,讓自己或者其它的線程運行,注意是讓自己或者其他線程運行,並不是單純的讓給其他線程
*
* example 小朋友們 一起搶一個球 現在被我搶到了,我突然大喊“我把球重新丟出去,誰先搶到是誰的”(注意是我
* 們,包含自己),然後大家重新進入搶球大戰
* 與wait 區別是 wait 讓出 cpu資源 自己不在加入 搶資源的 大軍
*/
public static native void yield();
note: 文章用於學習交流,如有錯誤之處,請大家指正