1. Thread实现了Runnable 接口
public class Thread implements Runnable
Runnable的源码非常简单,只有一个抽象方法。@FunctionalInterface是jdk1.8出现的函数式接口。用于Lamda表达式。
package java.lang;
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
2.Thrad类初始化阶段
这里类初始化阶段很简单,只调用了registerNatives方法。native修饰的方法,是由别的编程语言实现的,这里看不到源码。
<clinit>: 类构造器
public class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
/* 确保registerNatives是<clinit>要做的第一件事。*/
private static native void registerNatives();
static {
registerNatives();
}
}
3.成员变量
/* 名字 */
private volatile String 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 */
/* JVM状态 */
private boolean stillborn = false;
/* What will be run. */
/* 将要运行的目标 */
private Runnable target;
/* The group of this thread */
/* 线程组 */
private ThreadGroup group;
/* The context ClassLoader for this thread */
/* 此线程的上下文ClassLoader */
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
/* 此线程的继承的访问控制上下文 */
private AccessControlContext inheritedAccessControlContext;
/* For autonumbering anonymous threads. */
/* 用于自动编号线程。 */
private static int threadInitNumber;
/* threadInitNumber每次+1,该方法使用使用了synchronized修饰,所以是线程安全的*/
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
* The requested stack size for this thread, or 0 if the creator did
* not specify a stack size. It is up to the VM to do whatever it
* likes with this number; some VMs will ignore it.
*/
/* 线程请求的堆栈大小,未指定则为0;一些虚拟机将忽略它 */
private long stackSize;
/*
* JVM-private state that persists after native thread termination.
*/
private long nativeParkEventPointer;
/*
* Thread ID
*/
/* 线程ID */
private long tid;
/* For generating thread ID */
/* 用于生成线程ID */
private static long threadSeqNumber;
/* Java thread status for tools,
* initialized to indicate thread 'not yet started'
*/
/* 线程状态 */
private volatile int threadStatus = 0;
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
/**
* The argument supplied to the current call to
* java.util.concurrent.locks.LockSupport.park.
* Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
* Accessed using java.util.concurrent.locks.LockSupport.getBlocker
*/
volatile Object parkBlocker;
/* The object in which this thread is blocked in an interruptible I/O
* operation, if any. The blocker's interrupt method should be invoked
* after setting this thread's interrupt status.
*/
/* 在可中断的I / O操作中阻塞该线程的对象(如果有)。设置此线程的中断状态后,应调用阻塞程序的中断方法。 */
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
/**
* The minimum priority that a thread can have.
*/
/* 线程可以具有的最低优先级。 */
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
/* 线程的默认优先级。 */
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
/* 线程可以具有的最大优先级。 */
public final static int MAX_PRIORITY = 10;
4. 构造方法
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);
}
可以看到都是调用的init方法进行初始化。
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
/**
* 初始化线程。
*
* @param g 线程组
* @param target 调用run()方法的目标对象
* @param name 线程的名称
* @param stackSize 新线程的所需堆栈大小,或为0表示要忽略此参数。
* @param acc 要继承的AccessControlContext;如果为null,则为AccessController.getContext()
* @param inheritThreadLocals 如果为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();
}
/* 没有安全管理器则使用parent获取线程组 */
if (g == null) {
g = parent.getThreadGroup();
}
}
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);
/* 设置指定的堆栈大小 */
this.stackSize = stackSize;
/* Set thread ID */
//设置线程id
tid = nextThreadID();
}
5.常用方法
/**
* 返回对当前正在执行的线程对象的引用
* @return the currently executing thread.
*/
public static native Thread currentThread();
/**
给调度程序的提示是当前线程愿意放弃对处理器的当前使用。
*/
public static native void yield();
/**
* 根据系统计时器和调度程序的精度和准确性,使当前正在执行的线程进入休眠状态(暂时停止执行)达指定的毫秒数。
* 该线程不释放锁。
*/
public static native void sleep(long millis) throws InterruptedException;
/**
* 根据系统计时器和调度程序的精度和准确性,使当前正在执行的线程进入休眠状态(暂时停止执行)达指定的毫秒数加上指定的纳秒数。
* 该线程不释放锁。
* @param millis 睡眠时间(以毫秒为单位)
*
* @param nanos 额外的纳秒等待( 0-999999)
* @throws IllegalArgumentException 如果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);
}
/**
* 使该线程开始执行; Java虚拟机将调用此线程的run方法。
* 结果是两个线程正在同时运行:当前线程(从调用返回到start方法)和另一个线程(执行其run方法)。
* @exception IllegalThreadStateException 如果线程已经启动。
*/
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) {
/* 通知组线程t尝试启动失败。该线程组的状态会回滚,就好像从未尝试启动该线程一样。 再次将该线程视为线程组的未启动成员,并且允许随后尝试启动该线程。 */
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运行对象构造的,则将调用该Runnable对象的run方法;否则,将调用该方法。否则,此方法不执行任何操作并返回。Thread的子类应重写此方法。
*/
@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;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
/**
* 强制线程停止执行。
* 如果安装了安全管理器,则将其作为参数调用其checkAccess方法。这可能会导致引发SecurityException(在当前线程中)。
* 如果此线程与当前线程不同(即,当前线程正在尝试停止除自身以外的其他线程),则另外调用安全管理器的checkPermission方法(带有RuntimePermission(“ stopThread”)参数)。
* 同样,这可能导致抛出SecurityException(在当前线程中)。
* 此线程代表的线程被迫停止异常操作,并抛出一个新创建的ThreadDeath对象作为异常。
* 允许停止尚未启动的线程。
* 如果线程最终启动,则它立即终止。
* 除非必须执行一些特殊的清理操作,否则应用程序通常不应尝试捕获ThreadDeath(请注意,抛出ThreadDeath会导致try语句的finally子句在线程正式死亡之前被执行)。如果catch子句捕获了ThreadDeath对象,则重要的是重新抛出该对象,以便线程实际上死亡。
* 如果未捕获的异常是ThreadDeath的实例,则对未捕获的异常做出反应的顶级错误处理程序不会打印出消息,也不会以其他方式通知应用程序。
* @exception SecurityException 如果当前线程无法修改此线程。
*
* @deprecated
* 这种方法本质上是不安全的。 使用线程停止线程。停止会使它解锁它已锁定的所有监视器(这是未检查的ThreadDeath异常在堆栈中传播的自然结果)。
* 如果先前由这些监视器保护的任何对象处于不一致状态,则损坏的对象将变为其他线程可见,从而可能导致任意行为。
* stop的许多用法应由仅修改某些变量以指示目标线程应停止运行的代码代替。 目标线程应定期检查此变量,如果该变量指示要停止运行,则应有序地从其运行方法返回。
* 如果目标线程等待很长时间(例如,在条件变量上),则应使用interrupt方法来中断等待。
*/
@Deprecated
public final void stop() {
//获取安全管理器
SecurityManager security = System.getSecurityManager();
if (security != null) {
//检查当前正在运行的线程是否有权修改此线程。
checkAccess();
if (this != Thread.currentThread()) {
//如果基于当前有效的安全策略不允许给定权限指定的请求的访问权限,则引发SecurityException。
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
//零状态值对应于“ NEW”,它不能更改为非NEW,因为我们持有该锁。
if (threadStatus != 0) {
resume(); // 唤醒线程(如果已暂停)
}
// 调用stop0
stop0(new ThreadDeath());
}
@Deprecated
public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}
private native void stop0(Object o);
/**
* 中断此线程。
*
* @throws SecurityException 如果当前线程无法修改此线程
*/
public void interrupt() {
//当前线程是否是本身
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
//设置中断标志
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
private native void interrupt0();
/**
* 当前线程是否已被中断。
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/**
* 此线程是否已被中断。
*/
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* 测试某些线程是否已被中断。 根据传递的ClearInterrupted的值重置或不重置中断状态。
*/
private native boolean isInterrupted(boolean ClearInterrupted);
/**
* 销毁线程
*
* @deprecated
* 此方法最初设计为在不进行任何清理的情况下破坏此线程。
* 它所持有的任何监视器都将保持锁定状态。 但是,该方法从未实现。
* 如果要实施,那么它将在很大程度上很容易陷入死锁。
* 如果目标线程在销毁关键系统资源时拥有锁来保护它,那么任何线程都无法再次访问该资源。
* 如果另一个线程曾试图锁定此资源,则将导致死锁。这种僵局通常表现为“冻结”进程。
* @throws NoSuchMethodError always
*/
@Deprecated
public void destroy() {
throw new NoSuchMethodError();
}
/**
* 此线程是否存活
*
* @return 如果该线程处于活动状态,则为true;否则为false。
*/
public final native boolean isAlive();
/**
* 挂起该线程。
* 首先,不带参数调用此线程的checkAccess方法。 这可能导致抛出SecurityException(在当前线程中)。如果线程处于活动状态,则将其挂起,并且除非继续进行操作,否则它将不会进一步进行。
* @exception SecurityException 如果当前线程无法修改此线程。
* @deprecated
* 此方法已被弃用,因为它容易造成死锁。
* 如果目标线程在挂起时在监视器上保持锁定状态以保护关键系统资源,则在恢复目标线程之前,没有线程可以访问该资源。 如果将恢复目标线程的线程在调用resume之前尝试锁定此监视器,则会导致死锁。
* 这种僵局通常表现为“冻结”进程。
*/
@Deprecated
public final void suspend() {
checkAccess();
suspend0();
}
private native void suspend0();
/**
* 恢复挂起的线程。
*首先,不带参数调用此线程的checkAccess方法。 这可能导致抛出SecurityException(在当前线程中)。 如果线程处于活动状态但已挂起,则将继续执行该线程并允许其执行。
* @exception SecurityException 如果当前线程无法修改此线程.
* @deprecated
* 此方法仅可与suspend一起使用,因为容易造成死锁,因此已弃用。
*/
@Deprecated
public final void resume() {
checkAccess();
resume0();
}
private native void resume0();
/**
* 更改此线程的优先级。
* @param newPriority 将此线程设置为的优先级。
* @exception IllegalArgumentException
* 如果优先级不在MIN_PRIORITY到MAX_PRIORITY范围内引发IllegalArgumentException。
* @exception SecurityException 如果当前线程无法修改此线程。
*/
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);
}
}
private native void setPriority0(int newPriority);
/**
* 获取此线程的优先级。
*/
public final int getPriority() {
return priority;
}
/**
* 修改线程名称。
* @param name 此线程的新名称。
* @exception SecurityException 如果当前线程无法修改此线程。
*/
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;
}
private native void setNativeName(String name);
/**
* 返回该线程所属的线程组。如果该线程死亡(已停止),则此方法返回null。
*/
public final ThreadGroup getThreadGroup() {
return group;
}
/**
* 返回当前线程的线程组及其子组中活动线程的数量的估计值。 递归遍历当前线程的线程组中的所有子组。
* 返回的值只是一个估计值,因为此方法遍历内部数据结构时线程数可能会动态变化,并且可能会受某些系统线程的存在的影响。此方法主要用于调试和监视目的。
*/
public static int activeCount() {
return currentThread().getThreadGroup().activeCount();
}
/**
* 让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前,B不能工作。
* 此实现使用以isAlive为条件的等待调用循环。 当线程终止时,将调用notifyAll方法。
*
* @param millis 等待时间(以毫秒为单位)
* @throws IllegalArgumentException 如果millis的值为负
* @throws 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 {
//线程是存活状态则等待millis毫秒
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
/**
* 等待最多millis毫秒加上nanos纳秒,此线程死亡。
* @param millis 等待时间(以毫秒为单位)
*
* @param nanos 额外的纳秒等待( 0-999999)
*/
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);
}
/**
* 将此线程标记为守护程序线程或用户线程。 当运行的所有线程都是守护程序线程时,Java虚拟机将退出。
* 必须在线程启动之前调用此方法。
* @param on 如果为true,则将此线程标记为守护程序线程
* @throws IllegalThreadStateException 如果这个线程还存活。
* @throws SecurityException 如果当前线程无法修改此线程。
*
*/
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
/**
* 此线程是否是守护程序线程。
*
* @return 如果此线程是守护程序线程,则为true;否则为false。
*/
public final boolean isDaemon() {
return daemon;
}
/**
* 检查当前正在运行的线程是否有权修改此线程。
* 如果有安全管理器,则以该线程作为参数调用其checkAccess方法。这可能会导致引发SecurityException。
* @exception SecurityException
*/
public final void checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
6.线程状态
public enum State {
/**
* 新建状态(尚未启动的线程的线程状态)。
*/
NEW,
/**
* 就绪状态(可运行线程的线程状态。 处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统(例如处理器)的其他资源)。
*/
RUNNABLE,
/**
* 阻塞状态(处于阻塞状态的线程正在等待监视器锁定以输入同步块/方法,或者在调用wait之后重新输入同步块/方法)。
*/
BLOCKED,
/**
* 无限期等待状态(处于等待状态的线程正在等待另一个线程执行特定操作。)
* 调用下列方法会让线程处于等待状态:
* Object.wait
* Thread.join
* LockSupport.park
*/
WAITING,
/**
* 限时等待状态。
* 具有指定等待时间的以下方法:
* Thread.sleep
* Object.wait
* Thread.join
* LockSupport.parkNanos
* LockSupport.parkUntil
*/
TIMED_WAITING,
/**
* 终止状态(线程已完成执行)。
*/
TERMINATED;
}