谈起线程,大家是不是既熟悉有陌生,熟悉是因为我们启动任何一个程序、运行任何一个方法都伴随线程的存在,陌生是我们感受不到他的存在。下面我们一点点开始解开线程的面纱。
一、什么是线程
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
二、线程状态
创建线程(new状态):此步包含创建线程、及给线程分配资源(线程私有资源:程序计数器、Java栈、本地方法栈都是线程私有的,所以需要为线程分配一定的内存空间)
线程就绪(Runnable状态):线程就绪状态不代表线程能立刻运行,只是代表线程具备运行的能力,此时线程需要等待cup执行时间分配给此线程。
线程运行(Running状态):线程run方法执行
线程阻塞(Blocked状态):
- 线程在等待其他线程持有锁,如果线程获取锁则进入就绪状态。
- 线程处理阻塞IO返回,等待IO返回后则进入就绪状态。
线程不定时等待(Waiting状态):Waiting是一种特殊的Blocked,Waiting是主动进行的,Blocked是线程作用产生的。 比如:Object.waite()、Thread.join()、LockSupport.park()不加入超时时间。
线程定时等待(Timed_waiting):指线程在指定时间等待另外线程的状态,比如:Thread.sleep()、Object.wait()、Thread.join() 、LockSupport.parkNanos() 、LockSupport.parkUntil()。
线程终止(Terminated):已终止线程的线程状态。线程已经结束执行
下图是线程状态流程图,就绪状态是线程状态中转站
三、线程安全
如果一个类可以安全地被多个线程使用,它就是线程安全的。你无法对此论述提出任何争议,但也无法从中得到更多有意义的帮助。那么我们如何辨别线程安全与非线程安全的类?我们甚至又该如何理解“安全”呢?任何一个合理的“线程安全性”定义,其关键在于“正确性”的概念。在<<JAVA并发编程实践>>书中作者是这样定义的:一个类是是线程安全的,是指在被多个线程访问时,类可以持续进行正确的行为。或当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用方代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的。
四、Thread类重点方法列举
属性名称 | 描述 |
yield | 线程暂时放弃当前cpu使用,不释放锁,加入cup竞争 |
sleep | 线程休眠,不释放锁 |
start | 启动线程 |
exit | 入队列时的当前线程 |
stop | 强制关闭线程,释放锁可能导致脏数据 |
interrupt | 发出中断信号,如果判断线程中断退出线程,常用关闭线程。唤醒会终止阻塞 测试线程如使用了锁 sleep,同步锁的wait,socket的receiver,accept等方法时会清除中断状态 |
isInterrupted | 判断线程中断状态 |
isAlive | 线程是否是活跃状态 |
suspend | 线程挂起 后面的代码阻塞 且suspend不释放锁 |
resume | 将挂起的线程恢复回来 |
setPriority | 设置线程优先级别 优先级别分别为1、5、10 |
setDaemon | 是否是守护线程 |
join | 线程加入另外的线程 |
getStackTrace | 获取线程栈信息 |
setDefaultUncaughtExceptionHandler | 设置线程异常捕获 |
setUncaughtExceptionHandler | 设置全局线程异常捕获 |
五、源码解读
public class Thread implements Runnable {
/*该本地方法功能是注册其他本地方法的 详细介绍:产考文档1 */
private static native void registerNatives();
static {
registerNatives();
}
/*线程名称*/
private volatile char name[];
/*线程优先级 级别设置:MIN_PRIORITY=1、NORM_PRIORITY=5(默认)、MAX_PRIORITY=10*/
private int priority;
/*此变量未被使用 why*/
private Thread threadQ;
/*此变量未被使用 why*/
private long eetop;
/*此变量未被使用 why*/
private boolean single_step;
/* 是否是守护线程
* 设置守护线程:比如在线程运行前设置
* 守护线程 vs 用户线程:java守护线程退出交给jvm控制,可以在程序生命周期前退出
*/
private boolean daemon = false;
/* JVM state 此变量未被使用 why */
private boolean stillborn = false;
/* runable接口 */
private Runnable target;
/* 线程组:线程归属组 */
private ThreadGroup group;
/* 类加载器 */
private ClassLoader contextClassLoader;
/* 线程权限控制 TODO 超级难理解,参考文档3 */
private AccessControlContext inheritedAccessControlContext;
/* 线程id,具有唯一性. */
private static int threadInitNumber;
/*线程id 锁状态自增*/
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* 线程本地变量,作用域为一个线程内 其实ThreadLocal对象set的时候将值存储的是每个操作的线程内部 */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* 描述:跨线程传递信息
* 可继承的线程本地变量,新建子线程的时候将inheritableThreadLocals的值copy给子线程 比如:全链路监控场景用到此点
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
* 线程堆大小 虚拟机维护
*/
private long stackSize;
/*
* 在本地线程终止之后保留jvm私有状态 不懂TODO
*/
private long nativeParkEventPointer;
/*
* 线程id
*/
private long tid;
/* 用来生成线程ID */
private static long threadSeqNumber;
/*
* 线程状态初始化标示未启动
*/
private volatile int threadStatus = 0;
/*
* 线程同步自增方式生成id
*/
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
/**
* 用于调用java.util.concurrent.locks.LockSupport.park的参数
* 值由java.util.concurrent.locks.LockSupport.setBlocker设置
* 由java.util.concurrent.locks.LockSupport.getBlocker访问
*/
volatile Object parkBlocker;
/*
* 可中断I/O操作时这个线程的这个对象处于阻塞状态
* 当线程中断状态被设置时,这个blocker的interrupt方法应该被调用
* 可参考interrupt方法
*/
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
/* 设置blocker的值,通过java.nio代码中的 sun.misc.SharedSecrets进行调用
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
/**
* 最低优先级
*/
public final static int MIN_PRIORITY = 1;
/**
* 中等默认优先级
*/
public final static int NORM_PRIORITY = 5;
/**
* 最高优先级
*/
public final static int MAX_PRIORITY = 10;
/**
* 返回当前线程 native方法实现
*/
public static native Thread currentThread();
/**
* 线程暂时放弃当前cpu使用
*/
public static native void yield();
/**
* 线程放弃cpu使用,但是继续持有锁
*/
public static native void sleep(long millis) throws InterruptedException;
/**
* 休眠超时
*/
public static void sleep(long millis, int nanos)
throws InterruptedException {
//休眠时间必须大于0毫秒
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
//超时时间大于999999纳秒
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
//如果超时时间大于50000纳秒,等待自增1毫秒
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis);
}
/**
* 线程初始化
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}
/**
* 线程初始化
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name.toCharArray();
//获取当前线程
Thread parent = currentThread();
//对java代码权限控制,防止破坏系统(修改线程,窃取信息等) SecurityManager分析4
SecurityManager security = System.getSecurityManager();
if (g == null) {
/*获取线程组*/
if (security != null) {
g = security.getThreadGroup();
}
/* 获取父线程组 */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* 检查线程权限 TODO 什么权限? */
g.checkAccess();
/*
* TODO 不懂?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
//线程组未启动的线程加一
g.addUnstarted();
//设置线程组
this.group = g;
//父线程是否是守护线程给子线程
this.daemon = parent.isDaemon();
//线程权限设置
this.priority = parent.getPriority();
//检查类或者子类是否可以构造实例 TODO 没有太明白
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);
//此处重点精华 当inheritableThreadLocals不为空,copy父线程信息给子线程,跨线程之间信息传递依赖此原理
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* 设置线程id */
tid = nextThreadID();
}
/**
* TODO why
*/
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/**
* 线程构造方法
*/
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
/**
* 线程构造方法
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
/**
* 线程构造方法
*/
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc);
}
/**
* 线程名称初始化线程
*/
public Thread(String name) {
init(null, null, name, 0);
}
/**
* 线程组和线程名称初始化线程
*/
public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}
/**
* 线程名称+目标执行方法target初始化线程
*/
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
/**
* 线程名称+目标执行方法target初始化线程
*/
public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}
/**
* 线程名称+目标执行方法target+线程堆大小初始化线程
*/
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
/**
* 启动线程
*/
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) {
}
}
}
private native void start0();
/**
* 执行Runnable run方法
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
/**
* 线程退出
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Runnable run方法赋空 */
target = null;
/* 线程本地变量,作用域为一个线程内赋空 */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
/**
* 强制关闭线程 停掉线程和线程持有锁 可能导致数据不一致
*/
//表示本方法后续被弃用
@Deprecated
public final void stop() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// 线程状态不等于NEW
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
}
// 关闭当前线程
stop0(new ThreadDeath());
}
/**
*
*/
@Deprecated
public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}
/**
* 当前线程发出中断信号
* 关于关闭线程:通过控制中断控制控制线程停止任务,不要用stop可能会导致意外 详见Thread文档5 InterruptWaitThread
* PS:唤醒会终止阻塞 测试线程如使用了锁 sleep,同步锁的wait,socket的receiver,accept等方法时会清除中断状态
*/
public void interrupt() {
// 判断是否是当前线程
if (this != Thread.currentThread())
//线程权限校验 判断当前线程是否有权限修改线程
checkAccess();
synchronized (blockerLock) {
// Interruptible接口处理中断 关闭当前IO??
Interruptible b = blocker;
if (b != null) {
// 调用本地方法发出中断信号
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
/**
* 查看中断信号
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/**
* 查看当前中断信号是true还是false并且清除中断信号
*/
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* 本地方法 查看当前中断信号是true还是false并且清除中断信号
*/
private native boolean isInterrupted(boolean ClearInterrupted);
/**
* 方法已经弃用调回抛出异常
*/
@Deprecated
public void destroy() {
throw new NoSuchMethodError();
}
/**
* 本地方法判断线程是否活跃
*/
public final native boolean isAlive();
/**
* 线程挂起 后面的代码阻塞 且suspend不释放锁 TODO 发现thread一个bug,当两个锁获取中间不做任何操作suspend会释放掉锁
* 代码详细见:Thread文档5 SuspendThread
* ps:代码即将弃用
*/
@Deprecated
public final void suspend() {
checkAccess();
suspend0();
}
/**
* 将挂起的线程恢复回来
* 代码详细见:Thread文档5 SuspendAndResumeThread
*/
@Deprecated
public final void resume() {
checkAccess();
resume0();
}
/**
* 设置线程优先级
*/
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
/**
* 获取线程优先级
*/
public final int getPriority() {
return priority;
}
/**
* 设置线程名称
*/
public final synchronized void setName(String name) {
checkAccess();
this.name = name.toCharArray();
if (threadStatus != 0) {
setNativeName(name);
}
}
/**
* 返回线程名称
*/
public final String getName() {
return new String(name, true);
}
/**
* 返回线程组
*/
public final ThreadGroup getThreadGroup() {
return group;
}
/**
* 返回活跃线程数量
*/
public static int activeCount() {
/** 为什么要返回组内活跃线程数量 TODO */
return currentThread().getThreadGroup().activeCount();
}
/**
* 将活跃的线程组及其子组线程复制到指定的组 有什么用?TODO
*/
public static int enumerate(Thread tarray[]) {
return currentThread().getThreadGroup().enumerate(tarray);
}
/**
* 过时本地方法:此调用的定义取决于suspend()已弃用的。
* 此调用的结果从未明确定义,计算此线程中的堆栈帧数。线程必须被挂起
*/
@Deprecated
public native int countStackFrames();
/**
* 主等待子线程结束
*/
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 final synchronized void join(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++;
}
join(millis);
}
/**
* 主线程等待主线程超时
*/
public final void join() throws InterruptedException {
join(0);
}
/**
* 打印当前线程堆栈异常信息
*/
public static void dumpStack() {
new Exception("Stack trace").printStackTrace();
}
/**
* 设置当前线程为守护线程
*/
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
/**
* 是否是守护线程
*/
public final boolean isDaemon() {
return daemon;
}
/**
* 线程权限校验
*/
public final void checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
/**
* 线程信息输出
*/
public String toString() {
ThreadGroup group = getThreadGroup();
if (group != null) {
return "Thread[" + getName() + "," + getPriority() + "," +
group.getName() + "]";
} else {
return "Thread[" + getName() + "," + getPriority() + "," +
"" + "]";
}
}
/**
* 获取当前线程类加载器 用此好处防止执行方法类加载器不一致
*/
@CallerSensitive
public ClassLoader getContextClassLoader() {
if (contextClassLoader == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(contextClassLoader,
Reflection.getCallerClass());
}
return contextClassLoader;
}
/**
* 设置线程类加载器
*/
public void setContextClassLoader(ClassLoader cl) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
contextClassLoader = cl;
}
/**
* 检查一个对象是否加锁
*/
public static native boolean holdsLock(Object obj);
private static final StackTraceElement[] EMPTY_STACK_TRACE
= new StackTraceElement[0];
/**
* 打印线程栈调用链信息 dumpStack()打印堆栈异常信息 文档5 DumpStackThread
*/
public StackTraceElement[] getStackTrace() {
if (this != Thread.currentThread()) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
}
//判断线程是否活着
if (!isAlive()) {
return EMPTY_STACK_TRACE;
}
//获取当前线程栈信息
StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
StackTraceElement[] stackTrace = stackTraceArray[0];
//
if (stackTrace == null) {
stackTrace = EMPTY_STACK_TRACE;
}
return stackTrace;
} else {
// Don't need JVM help for current thread
return (new Exception()).getStackTrace();
}
}
/**
* 获取当前项目所有线程栈信息
*/
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
// check for getStackTrace permission
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
security.checkPermission(
SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
}
//获取当前项目所有线程?TODO
Thread[] threads = getThreads();
StackTraceElement[][] traces = dumpThreads(threads);
Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
for (int i = 0; i < threads.length; i++) {
StackTraceElement[] stackTrace = traces[i];
if (stackTrace != null) {
m.put(threads[i], stackTrace);
}
// else terminated so we don't put it in the map
}
return m;
}
private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new RuntimePermission("enableContextClassLoaderOverride");
/** 构建缓存类 TODO */
private static class Caches {
/** cache of subclass security audit results */
static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
new ConcurrentHashMap<>();
/** queue for WeakReferences to audited subclasses */
static final ReferenceQueue<Class<?>> subclassAuditsQueue =
new ReferenceQueue<>();
}
/**
* 检查类或者子类是否可以构造实例 TODO 没有太明白
*/
private static boolean isCCLOverridden(Class<?> cl) {
if (cl == Thread.class)
return false;
processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = Boolean.valueOf(auditSubclass(cl));
Caches.subclassAudits.putIfAbsent(key, result);
}
return result.booleanValue();
}
/**
* 检查子类是否支持重写 TODO 用途?
*/
private static boolean auditSubclass(final Class<?> subcl) {
Boolean result = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
public Boolean run() {
for (Class<?> cl = subcl;
cl != Thread.class;
cl = cl.getSuperclass())
{
try {
cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
try {
Class<?>[] params = {ClassLoader.class};
cl.getDeclaredMethod("setContextClassLoader", params);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
}
return Boolean.FALSE;
}
}
);
return result.booleanValue();
}
//获取线程栈信息集合
private native static StackTraceElement[][] dumpThreads(Thread[] threads);
//获取应用线程集合
private native static Thread[] getThreads();
/**
* 获取线程id
*/
public long getId() {
return tid;
}
/**
* 线程状态枚举
*/
public enum State {
/**
* 创建
*/
NEW,
/**
* 就绪
*/
RUNNABLE,
/**
* 阻塞
*/
BLOCKED,
/**
* 不定时等待
*/
WAITING,
/**
* 定时等待
*/
TIMED_WAITING,
/**
* 线程终止
*/
TERMINATED;
}
/**
* 获取线程状态
*/
public State getState() {
// 调用sun vm api从虚拟机获取线程状态 TODO 流程深奥
return sun.misc.VM.toThreadState(threadStatus);
}
/**
* 线程异常处理 优先级高于setDefaultUncaughtExceptionHandler
* 代码详细见:Thread文档5 ExceptionThead
*/
@FunctionalInterface
public interface UncaughtExceptionHandler {
/**
* 如果需要捕获线程异常实现此方法
*/
void uncaughtExcetption(Thread t, Throwable e);
}
// null unless explicitly set
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
// null unless explicitly set
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
/**
* 线程全局异常捕获
* 代码详细见:Thread文档5 ExceptionThead
*/
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
new RuntimePermission("setDefaultUncaughtExceptionHandler")
);
}
defaultUncaughtExceptionHandler = eh;
}
/**
* 获取全局异常
*/
public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
return defaultUncaughtExceptionHandler;
}
/**
* 获取普通异常
*/
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
/**
* 设置异常
*/
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
checkAccess();
uncaughtExceptionHandler = eh;
}
/**
* 程序对法发送未捕获的异常,此方法只能有jvm虚拟机调用
*/
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
/**
* 用途?TODO
*/
static void processQueue(ReferenceQueue<Class<?>> queue,
ConcurrentMap<? extends
WeakReference<Class<?>>, ?> map)
{
Reference<? extends Class<?>> ref;
while((ref = queue.poll()) != null) {
map.remove(ref);
}
}
/**
* Weak key for Class objects.
**/
static class WeakClassKey extends WeakReference<Class<?>> {
/**
* saved value of the referent's identity hash code, to maintain
* a consistent hash code after the referent has been cleared
*/
private final int hash;
/**
* Create a new WeakClassKey to the given object, registered
* with a queue.
*/
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
super(cl, refQueue);
hash = System.identityHashCode(cl);
}
/**
* Returns the identity hash code of the original referent.
*/
@Override
public int hashCode() {
return hash;
}
/**
*
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof WeakClassKey) {
Object referent = get();
return (referent != null) &&
(referent == ((WeakClassKey) obj).get());
} else {
return false;
}
}
}
/** The current seed for a ThreadLocalRandom */
@sun.misc.Contended("tlr")
long threadLocalRandomSeed;
/** Probe hash value; nonzero if threadLocalRandomSeed initialized */
@sun.misc.Contended("tlr")
int threadLocalRandomProbe;
/** Secondary seed isolated from public ThreadLocalRandom sequence */
@sun.misc.Contended("tlr")
int threadLocalRandomSecondarySeed;
/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void stop0(Object o);
private native void suspend0();
private native void resume0();
private native void interrupt0();
private native void setNativeName(String name);
}
参考文档:
涉及其他知识文档: