Thread类
public class Thread implements Runnable
Thread实现Runnable接口,实现run方法
private static native void registerNatives();
static {
registerNatives();
}
从上面的代码中看到定义了一个静态初始化块,我们知道当创建Java对象时,系统总是先调用静态初始化块
在上面的静态初始化块中调用了registerNatives()方法,并且使用了private来修饰,表面这个方法是私有的并不被外部调用。
在Java中使用native关键字修饰的方法,说明此方法并不是由Java中完成的,而是通过C/C++来完成的,并被编译成.dll,之后才由Java调用。方法的具体实现是在dll文件中,当然对于不同平台实现的细节也有所不同,以上registerNatives()方法主要作用就是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦
属性
private char name[]; //线程名字
private int priority; //优先级
private Thread threadQ; //未知
private long eetop; //未知
/* Whether or not to single_step this thread. */
//是否是单步执行
private boolean single_step;
/* Whether or not the thread is a daemon thread. */
//是否是守护线程
private boolean daemon = false;
/* JVM state */
// 虚拟机状态
private boolean stillborn = false;
/* What will be run. */
//将会被执行的Runnable.
private Runnable target;
/* The group of this thread */
//这个线程的组
private ThreadGroup group;
/* The context ClassLoader for this thread */
//这个线程的上下文
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
//继承的请求控制
private AccessControlContext inheritedAccessControlContext;
//默认线程的自动编号
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
//该线程请求的堆栈大小 默认一般都是忽略
private long stackSize;
//未知
private long nativeParkEventPointer;
// 每个线程都有专属ID,但名字可能重复
private long tid;
//用来生成thread ID
private static long threadSeqNumber;
//得到下个thread ID
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
//标识线程状态,默认是线程未启动
private int threadStatus = 0;
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
//当前线程附属的ThreadLocal,而ThreadLocalMap会被ThreadLocal维护)
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
// 主要作用:为子线程提供从父线程那里继承的值
//在创建子线程时,子线程会接收所有可继承的线程局部变量的初始值,以获得父线程所具有的值
// 创建一个线程时如果保存了所有 InheritableThreadLocal 对象的值,那么这些值也将自动传递给子线程
//如果一个子线程调用 InheritableThreadLocal 的 get() ,那么它将与它的父线程看到同一个对象
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
// 中断阻塞器:当线程发生IO中断时,需要在线程被设置为中断状态后调用该对象的interrupt方法
volatile Object parkBlocker;
//阻塞器锁,主要用于处理阻塞情况
private volatile Interruptible blocker;
//阻断锁
private Object blockerLock = new Object();
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;
/* If stop was called before start */
//判断stop是否在Start前
private boolean stopBeforeStart;
/* Remembered Throwable from stop before start */
//未知
private Throwable throwableFromStop;
构造方法
//g是线程组,target被调用RUN方法的目标对象,name新线程的名字,stackSize用于新线程分配所需堆栈大小
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
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);
}
native方法
//获得当前的线程
public static native Thread currentThread();
//使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了
public static native void yield();
//静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。 当线程睡眠时,它睡在某个地方,在苏醒之前不会返回到可运行状态。 当睡眠时间到期,则返回到可运行状态。
public static native void sleep(long millis) throws InterruptedException;
//开始线程
private native void start0();
//设置线程优先级
private native void setPriority0(int newPriority);
//停止线程
private native void stop0(Object o);
// 线程挂起(暂停)
private native void suspend0();
//将一个挂起线程复活继续执行
private native void resume0();
//该线程的中断状态将被设置
private native void interrupt0();
//判断线程是否存活
public final native boolean isAlive();
//当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
public static native boolean holdsLock(Object obj);
普通方法
//millis为毫秒,nanos为纳秒,1000纳秒=1毫秒,其他跟sleep方法一样
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);
}
//这是线程初始化方法
//g是线程组,target被调用RUN方法的目标对象,name新线程的名字,stackSize用于新线程分配所需堆栈大小
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
//获得当前线程
Thread parent = currentThread();
//获得系统的安全管理器
SecurityManager security = System.getSecurityManager();
if (g == null) {
//安全检查
if (security != null) {
g = security.getThreadGroup();
}
//设置线程组
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
//检查是否允许调用线程修改线程组参数
g.checkAccess();
/*
* Do we have the required permissions?
*/
//是否有权限访问
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
//往线程组添加线程但未启动
g.addUnstarted();
//线程组
this.group = g;
//是否守护线程
this.daemon = parent.isDaemon();
//优先级
this.priority = parent.getPriority();
//线程名
this.name = name.toCharArray();
//每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext = AccessController.getContext();
this.target = target;
setPriority(priority);
if (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();
}
//使线程进入可执行(runnable状态)的状态
public synchronized void start() {
//验证线程的状态,如果线程已启动则抛异常
if (threadStatus != 0)
throw new IllegalThreadStateException();
//向线程组里添加此线程
group.add(this);
//使线程进入可执行(runnable状态)的状态
start0();
//如果验证停止前于开始
if (stopBeforeStart) {
//停止线程
stop0(throwableFromStop);
}
}
//使线程从可运行状态转化为运行状态
public void run() {
if (target != null) {
target.run();
}
}
//这个方法是在Run方法执行结束后用于结束线程的。通过单步调试一个线程发现执行完run方法之后会进入exit方法。
private void exit() {
if (group != null) {
group.remove(this);
group = null;
}
target = null;
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
//停止线程
public final void stop() {
// If the thread is already dead, return.
// A zero status value corresponds to "NEW".
//如果线程已启动或者已经销毁
if ((threadStatus != 0) && !isAlive()) {
return;
}
//执行stop1
stop1(new ThreadDeath());
}
@Deprecated
public final synchronized void stop(Throwable obj) {
stop1(obj);
}
private final synchronized void stop1(Throwable th) {
//获得系统的安全管理器
SecurityManager security = System.getSecurityManager();
//如果安全管理器为空
if (security != null) {
//检查是否允许调用线程修改线程组参数
checkAccess();
//如果这个线程不是当前线程或者这个线程以销毁
if ((this != Thread.currentThread()) ||
(!(th instanceof ThreadDeath))) {
//如果所请求的访问,通过给定的权限,指定的安全策略不允许根据当前有效的方法将抛出一个SecurityException。
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW"
//如果线程已启动
if (threadStatus != 0) {
//如果线程被挂起则唤醒
resume(); // Wake up thread if it was suspended; no-op otherwise
//停止线程
stop0(th);
} else {
// Must do the null arg check that the VM would do with stop0
//如果线程为空抛空指针
if (th == null) {
throw new NullPointerException();
}
// Remember this stop attempt for if/when start is used
stopBeforeStart = true;
throwableFromStop = th;
}
}
//线程挂起
public final void suspend() {
checkAccess();
suspend0();
}
//线程从挂起到唤醒
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 void setName(String name) {
checkAccess();
//将String转换成char数组
this.name = name.toCharArray();
}
//得到线程名称
public final String getName() {
return String.valueOf(name);
}
//获得当前的线程的线程组
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);
}
//堵塞当前线程,使其处于等待状态,因为子线程执行的时间可能比主线程执行时间还长,所以join是主线程需要在它执行完后再销毁。当然也可以加参数join(long millis, int nanos),使其等待N秒N毫秒,如果它已经处于join方法,则报InterruptedException 。
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 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() + "," +
"" + "]";
}
}
//返回该线程的上下文 ClassLoader。上下文 ClassLoader 由线程创建者提供,供运行于该线程中的代码在加载类和资源时使用。如果未设定,则默认为父线程的 ClassLoader 上下文。原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器。
//首先,如果有安全管理器,并且调用者的类加载器不是 null,也不同于其上下文类加载器正在被请求的线程上下文类加载器的祖先,则通过 RuntimePermission("getClassLoader") 权限调用该安全管理器的 checkPermission 方法,查看是否可以获取上下文 ClassLoader。
public ClassLoader getContextClassLoader() {
if (contextClassLoader == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl != null && ccl != contextClassLoader &&
!contextClassLoader.isAncestor(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
return contextClassLoader;
}
//设置该线程的上下文 ClassLoader。上下文 ClassLoader 可以在创建线程设置,并允许创建者在加载类和资源时向该线程中运行的代码提供适当的类加载器。
//首先,如果有安全管理器,则通过 RuntimePermission("setContextClassLoader") 权限调用其 checkPermission 方法,查看是否可以设置上下文 ClassLoader。
public void setContextClassLoader(ClassLoader cl) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
contextClassLoader = cl;
}
// 返回一个表示该线程堆栈转储的堆栈跟踪元素数组。
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<Thread, StackTraceElement[]>(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;
}
今天就先讲到这里,后续还会继续探索