线程Thread
Java的线程对应OS中的线程,相当于对OS线程的封装
作用 | 线程 |
---|---|
JVM的基本操作 如 自动内存管理、取消偏向锁 线程dump、线程挂起等 |
VM Thread |
负责执行定时操作 | Periodic task Thread |
负责垃圾回收 | GC Thread |
负责将字节码编译为本地代码 | Compiler Thread |
负责响应JVM外部信号 | Singal Dispatcher Thread |
意义 | 成员变量 | 类型 |
---|---|---|
线程ID | tid | long |
线程序列数 | threadSeqNumber | static long |
线程名 | name | String |
优先级 | priority | int |
是否守护线程 | daemon | boolean |
要执行的任务 | target | Runnable |
线程数组 | group | ThreadGroup |
状态码 New、Runnable、Bolcked、Waiting、Timed_Waiting、Terminated |
threadStatus | int |
线程对应的本地变量map | threadLocals | ThreadLocal.ThreadLocalMap |
作用 | API |
---|---|
创建线程 | Thread(ThreadGroup group, Runnable target, String name, long stackSize) |
启动 | start |
强制结束 | stop |
等待线程结束 | join |
当前线程进入等待 | sleep |
调用run方法 | run |
线程让步 | yield |
是否存活 | isAlive |
设置未捕获异常处理器 | setUncaughtExceptionHandler |
获取未捕获异常 | getUncaughtException |
UncaughtExceptionHandler 未捕获异常处理器,当线程发生非受检异常而终止时,JVM调用线程未捕获异常处理器的 uncaughtException方法
钩子
使用Runtime类的addShutdownHook(Thread hook)添加
ApplicationShutdownHooks.add(hook)
IdentityHashMap
源码解析(native方法就不解析了)
创建
构造函数调用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();
}
}
//确定权限——调用securityManager检查当前线程组是否拥有RuntimePermission("modifyThreadGroup")权限
g.checkAccess();
//确定权限——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() {
//状态必须为“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();