線程Thread
Java的線程對應(yīng)OS中的線程拇勃,相當于對OS線程的封裝
作用 | 線程 |
---|---|
JVM的基本操作<br />如 自動內(nèi)存管理祭饭、取消偏向鎖<br />線程dump缀踪、線程掛起等 | VM Thread |
負責執(zhí)行定時操作 | Periodic task Thread |
負責垃圾回收 | GC Thread |
負責將字節(jié)碼編譯為本地代碼 | Compiler Thread |
負責響應(yīng)JVM外部信號 | Singal Dispatcher Thread |
意義 | 成員變量 | 類型 |
---|---|---|
線程ID | tid | long |
線程序列數(shù) | threadSeqNumber | static long |
線程名 | name | String |
優(yōu)先級 | priority | int |
是否守護線程 | daemon | boolean |
要執(zhí)行的任務(wù) | target | Runnable |
線程數(shù)組 | group | ThreadGroup |
狀態(tài)碼<br />New虐译、Runnable雷酪、Bolcked、Waiting释涛、Timed_Waiting加叁、Terminated | threadStatus | int |
線程對應(yīng)的本地變量map | threadLocals | ThreadLocal.ThreadLocalMap |
作用 | API |
---|---|
創(chuàng)建線程 | Thread(ThreadGroup group, Runnable target, String name, long stackSize) |
啟動 | start |
強制結(jié)束 | stop |
等待線程結(jié)束 | join |
當前線程進入等待 | sleep |
調(diào)用run方法 | run |
線程讓步 | yield |
是否存活 | isAlive |
設(shè)置未捕獲異常處理器 | setUncaughtExceptionHandler |
獲取未捕獲異常 | getUncaughtException |
UncaughtExceptionHandler 未捕獲異常處理器,當線程發(fā)生非受檢異常而終止時唇撬,JVM調(diào)用線程未捕獲異常處理器的 uncaughtException方法
鉤子
使用Runtime類的addShutdownHook(Thread hook)添加
ApplicationShutdownHooks.add(hook)
IdentityHashMap<Thread,Thread> hooks.put(hook,hook)
源碼解析(native方法就不解析了)
創(chuàng)建
構(gòu)造函數(shù)調(diào)用init方法初始化線程
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
//令securityManager獲取當前線程的ThreadGroup
if (security != null) {
g = security.getThreadGroup();
}
//自行獲取當前線程的ThreadGroup
if (g == null) {
g = parent.getThreadGroup();
}
}
//確定權(quán)限——調(diào)用securityManager檢查當前線程組是否擁有RuntimePermission("modifyThreadGroup")權(quán)限
g.checkAccess();
//確定權(quán)限——RuntimePermission("enableContextClassLoaderOverride")
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(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.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
啟動
public synchronized void start() {
//狀態(tài)必須為“NEW”
if (threadStatus != 0)
throw new IllegalThreadStateException();
//添加至線程組
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 */
}
}
}
private native void start0();
休眠
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);
}
等待線程
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;
}
}
}
讓步
public static native void yield();