进程
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
线程
线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。
线程是程序中的执行线程。Java虚拟机允许应用程序同时运行多个执行线程。每个线程都有优先级。优先级较高的线程优先于优先级较低的线程执行。每个线程也可以标记为守护进程,也可以不标记为守护进程。当在某个线程中运行的代码创建一个新的<code>线程</code>对象时,新线程的优先级最初设置为等于创建线程的优先级,并且仅当创建线程是守护进程时才是守护进程线程。每个线程都有一个用于标识的名称。多个线程可能具有相同的名称。如果在创建线程时未指定名称,则会为其生成新名称。
类名
public class Thread implements Runnable
变量
/* 线程名称 */
private volatile String name;
/* 线程优先级 */
private int priority;
private Thread threadQ;//类中没有使用到
private long eetop;//类中没有使用到
/* 是否单步执行此线程 */
private boolean single_step;
/* 线程是否为守护进程线程。 */
private boolean daemon = false;
/* JVM state */
private boolean stillborn = false;
/* 将要运行的内容 */
private Runnable target;
/* 线程组 */
private ThreadGroup group;
/* 此线程的上下文类加载器*/
private ClassLoader contextClassLoader;
/* 此线程继承的AccessControlContext*/
private AccessControlContext inheritedAccessControlContext;
/* 用于自动编号匿名线程. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* 与此线程相关的ThreadLocal值。此映射由ThreadLocal类维护。*/
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* 与此线程相关的可继承线程本地值。此映射由InheritableThreadLocal类维护。
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
* 此线程请求的堆栈大小,如果创建者未指定堆栈大小,则为0。一些VM会忽略它
*/
private long stackSize;
/*
* 在本机线程终止后持续存在的JVM私有状态
*/
private long nativeParkEventPointer;
线程创建
1.继承Thread类
public class ThreadDemo extends Thread {
@Override
public void run() {
System.out.println("Thread");
}
}
2.实现Runnable接口
public class ThreadDemo implements Runnable {
@Override
public void run() {
System.out.println("Runnable");
}
}
3.使用Callable和Future
public class ThreadDemo implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName());
return Thread.currentThread().getName();
}
public static void main(String[] args) throws Exception {
Callable<String> callable = new ThreadDemo();
FutureTask<String> ft = new FutureTask<>(callable);
new Thread(ft,"threadName").start();
System.out.println(ft.get());
}
}
线程状态
start()
/**
* 使此线程开始执行;Java虚拟机调用此线程的run方法。
*/
public synchronized void start() {
/**
*对于VM创建/设置的主方法线程或“系统”组线程,
*不调用此方法。将来添加到此方法的任何新功能可能也必须添加到VM中。
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* 通知group此线程即将启动,
* 以便可以将其添加到组的线程列表中,并且可以减少组的未启动计数 */
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();
run()
/**
* 如果此线程是使用单独的Runnable run对象构造的,
* 则调用该Runnable对象的run方法;否则,此方法不执行任何操作和返回。
* 子类需要重写这个方法
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
真正启动线程的是start()方法而不是run(),run()和普通的成员方法一样,可以重复使用,但不能启动一个新线程。
sleep()和wait()的区别
sleep为线程的方法,而wait为Object的方法,他们的功能相似,最大本质的区别是:sleep不释放锁,wait释放锁。
sleep(milliseconds)可以用时间指定来使他自动醒过来,如果时间不到你只能调用interreput()来终止线程;wait()可以用notify()/notifyAll()直接唤起。
public class ThreadDemo extends Thread {
int number = 10;
public synchronized void add(){
number = number+1;
System.out.println(number);
}
public synchronized void multiply() throws InterruptedException {
//Thread.sleep(1000);
this.wait(0);
number = number*100;
}
@Override
public void run() {
add();
}
public static void main(String[] args) throws InterruptedException {
ThreadDemo demo = new ThreadDemo();
demo.start();
demo.interrupt();
Thread.sleep(1000);
System.out.println(demo.number);
}
}
当调用sleep方法输出 1001,调用wait方法输出1100。
join
/**
* 等待此线程结束.
*/
public final void join() throws InterruptedException {
join(0);
}
/**
* 最多等待millis毫秒,0意味着永远等待。
*/
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;
}
}
}
Join()方法,使调用此方法的线程wait(),直到调用此方法的线程对象所在的线程执行完毕后被唤醒。
interrupt
/**
* 中断此线程.
*/
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); //只是为了设置中断标志
b.interrupt(this);
return;
}
}
interrupt0();
}
当对一个线程,调用 interrupt() 时,
① 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。仅此而已。
② 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。
public class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
/* 线程名称 */
private volatile String name;
/* 线程优先级 */
private int priority;
private Thread threadQ;//类中没有使用到
private long eetop;//类中没有使用到
/* 是否单步执行此线程 */
private boolean single_step;
/* 线程是否为守护进程线程。 */
private boolean daemon = false;
/* JVM state */
private boolean stillborn = false;
/* 将要运行的内容 */
private Runnable target;
/* 线程组 */
private ThreadGroup group;
/* 此线程的上下文类加载器*/
private ClassLoader contextClassLoader;
/* 此线程继承的AccessControlContext*/
private AccessControlContext inheritedAccessControlContext;
/* 用于自动编号匿名线程. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* 与此线程相关的ThreadLocal值。此映射由ThreadLocal类维护。*/
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* 与此线程相关的可继承线程本地值。此映射由InheritableThreadLocal类维护。
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
* 此线程请求的堆栈大小,如果创建者未指定堆栈大小,则为0。一些VM会忽略它
*/
private long stackSize;
/*
* 在本机线程终止后持续存在的JVM私有状态
*/
private long nativeParkEventPointer;
/*
* Thread ID
*/
private long tid;
/* 用于生成线程ID */
private static long threadSeqNumber;
/* Java线程状态,已初始化表示线程“尚未启动”
*/
private volatile int threadStatus = 0;
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操作中被阻塞的对象(如果有)。
* 设置此线程的中断状态后,应调用阻止程序的中断方法。
*/
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;
/**
* 返回对当前正在执行的线程对象的引用。
*/
public static native Thread currentThread();
/**
* 向调度程序提示当前线程愿意放弃当前对处理器的使用。
* Yield是一个启发式的尝试,旨在改进线程之间的相对进程,
* 否则会过度使用CPU。它的使用应该与详细的概要分析和基准测试相结合,
* 以确保它实际具有预期的效果。
* 使用这种方法是不合适的。它可能对调试或测试有用。
*/
public static native void yield();
/**
* 根据系统计时器和调度程序的精度和准确性,
* 使当前执行的线程睡眠(暂时停止执行)指定的毫秒数。
* 线程不会失去任何监视器的所有权.
*/
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);
}
/**
* 使用当前AccessControlContext初始化线程.
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
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) {
if (security != null) {
g = security.getThreadGroup();
}
if (g == null) {
g = parent.getThreadGroup();
}
}
/* 无论是否显式传入threadgroup,都可以进行checkAccess. */
g.checkAccess();
/*
* 检查权限
*/
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();
}
@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, false);
}
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(String name) {
init(null, null, name, 0);
}
public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
/**
* 使此线程开始执行;Java虚拟机调用此线程的run方法。
*/
public synchronized void start() {
/**
*对于VM创建/设置的主方法线程或“系统”组线程,
*不调用此方法。将来添加到此方法的任何新功能可能也必须添加到VM中。
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* 通知group此线程即将启动,
* 以便可以将其添加到组的线程列表中,并且可以减少组的未启动计数 */
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();
/**
* 如果此线程是使用单独的Runnable run对象构造的,
* 则调用该Runnable对象的run方法;否则,此方法不执行任何操作和返回。
* 子类需要重写这个方法
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
/**
* 这个方法被系统调用,以便在实际退出之前给线程一个清理的机会。
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* 加快释放这些资源 */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
/**
* 中断此线程.
*/
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); //只是为了设置中断标志
b.interrupt(this);
return;
}
}
interrupt0();
}
/**
* 当前线程是否已中断.
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/**
* 此线程是否已中断.
*/
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* 某个线程是否被中断。中断状态是否基于传递的ClearInterrupted值重置。
*/
private native boolean isInterrupted(boolean ClearInterrupted);
/**
* 此线程是否处于活动状态。如果线程已启动但尚未死亡,则它是活动的
*/
public final native boolean isAlive();
/**
* 更改此线程的优先级.
*/
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();
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
if (threadStatus != 0) {
setNativeName(name);
}
}
/**
* 返回线程名称
*/
public final String getName() {
return name;
}
/**
* 返回此线程所属的线程组。
* 如果此线程已终止(已停止),则此方法返回null
*/
public final ThreadGroup getThreadGroup() {
return group;
}
/**
* 返回当前线程的及其子组中活动线程数的估计值。
* 递归地迭代当前线程的线程组中的所有子组。
*/
public static int activeCount() {
return currentThread().getThreadGroup().activeCount();
}
/**
*将当前线程的线程组及其子组中的每个活动线程复制到指定数组中
*/
public static int enumerate(Thread tarray[]) {
return currentThread().getThreadGroup().enumerate(tarray);
}
/**
* 等待此线程结束.
*/
public final void join() throws InterruptedException {
join(0);
}
/**
* 最多等待millis毫秒,0意味着永远等待。
*/
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;
}
}
}
/**
* 最多等待millis毫秒加上nanos纳秒,使此线程死亡。
*/
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 static void dumpStack() {
new Exception("Stack trace").printStackTrace();
}
/**
* 将此线程标记为守护线程或用户线程。
* 当运行的唯一线程都是守护进程线程时,java虚拟机退出。
* 必须在启动线程之前调用此方法
*/
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;
}
/**
* 当前线程持有指定对象上的监视器锁时,返回true。
*/
public static native boolean holdsLock(Object obj);
private static final StackTraceElement[] EMPTY_STACK_TRACE
= new StackTraceElement[0];
/**
* 返回表示此线程堆栈转储的堆栈跟踪元素数组。
*/
public StackTraceElement[] getStackTrace() {
if (this != Thread.currentThread()) {
// check for getStackTrace permission
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
}
// optimization so we do not call into the vm for threads that
// have not yet started or have terminated
if (!isAlive()) {
return EMPTY_STACK_TRACE;
}
StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
StackTraceElement[] stackTrace = stackTraceArray[0];
// a thread that was alive during the previous isAlive call may have
// since terminated, therefore not having a stacktrace.
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);
}
// Get a snapshot of the list of all threads
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");
/** cache of subclass security audit results */
/* Replace with ConcurrentReferenceHashMap when/if it appears in a future
* release */
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<>();
}
/**
* Verifies that this (possibly subclass) instance can be constructed
* without violating security constraints: the subclass must not override
* security-sensitive non-final methods, or else the
* "enableContextClassLoaderOverride" RuntimePermission is checked.
*/
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();
}
/**
* Performs reflective checks on given subclass to verify that it doesn't
* override security-sensitive non-final methods. Returns true if the
* subclass overrides any of the methods, false otherwise.
*/
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();
/**
* 返回此线程的标识符.
*/
public long getId() {
return tid;
}
/**
* 线程状态.
*/
public enum State {
/**
* 尚未启动的线程的线程状态.
*/
NEW,
/**
* 可运行线程的线程状态.
*/
RUNNABLE,
/**
* 阻塞状态
*/
BLOCKED,
/**
* 等待状态.
*/
WAITING,
/**
* 具有指定等待时间的等待线程的线程状态。
*/
TIMED_WAITING,
/**
*终止状态
*/
TERMINATED;
}
/**
* 返回线程状态
*/
public State getState() {
// get current thread state
return sun.misc.VM.toThreadState(threadStatus);
}
// Added in JSR-166
/**
* 当线程因未捕获异常而突然终止时调用的处理程序接口.
*/
@FunctionalInterface
public interface UncaughtExceptionHandler {
/**
* 当给定线程由于给定的未捕获异常而终止时调用的。
*/
void uncaughtException(Thread t, Throwable e);
}
// null unless explicitly set
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
// null unless explicitly set
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
/**
* 设置当线程由于未捕获异常而突然终止时调用的默认处理程序,
* 并且尚未为该线程定义其他处理程序。
*/
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;
}
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
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<?>> {
private final int hash;
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
super(cl, refQueue);
hash = System.identityHashCode(cl);
}
@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);
}
更多精彩内容请关注微信公众号: