线程源码阅读
本地资源加载
private static native void registerNatives();
static {
registerNatives();
}
JNI编程后面再专门研究
Thread所有的成员变量、类变量
//线程名称,创建线程是如果没有指定则会默认生成一个
private volatile String name;
//线程优先级 最小1 最大10
private int priority;
private Thread threadQ;
private long eetop;
// 是否单步执行此线程
private boolean single_step;
// 此线程是否为守护线程
private boolean daemon = false;
// Java虚拟机的状态
private boolean stillborn = false;
//真正在线程中执行的任务
private Runnable target;
//当前线程所在的线程组
private ThreadGroup group;
//当前线程的类加载器
private ClassLoader contextClassLoader;
//访问控制上下文
private AccessControlContext inheritedAccessControlContext;
//为匿名线程生成名称的编号
private static int threadInitNumber;
//与此线程相关的ThreadLocal,这个Map维护的是ThreadLocal类
ThreadLocal.ThreadLocalMap threadLocals = null;
//与此线程相关的ThreadLocal
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
//当前线程请求的堆栈大小,如果未指定堆栈大小,则会交给JVM来处理
private long stackSize;
//线程终止后存在的JVM私有状态
private long nativeParkEventPointer;
//线程id
private long tid;
//用来生成线程id
private static long threadSeqNumber;
//当前线程的状态,默认为0,标识当前线程还没有启动
private volatile int threadStatus = 0;
/*提供给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();
//线程最小优先级
public final static int MIN_PRIORITY = 1;
//线程创建后的默认优先级
public final static int NORM_PRIORITY = 5;
//线程最大优先级
public final static int MAX_PRIORITY = 10;
//空的堆栈信息
private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];
//子类实现的运行时权限
private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new RuntimePermission("enableContextClassLoaderOverride");
// 未捕获的异常处理程序 除非明确设置,否则为null
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
// 默认的未捕获异常处理程序 除非明确设置,否则为null
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
//以下三个最初未初始化的字段专门由类java.util.concurrent.ThreadLocalRandom管理。这些字段用于在并发代码中构建高性能的 PRNG,因此我们不会冒意外的错误共享的风险。因此,这些字段用@Contended隔离
// ThreadLocalRandom的当前种子
@sun.misc.Contended("tlr")
long threadLocalRandomSeed;
//探针哈希值;如果threadLocalRandomSeed初始化,则为非零
@sun.misc.Contended("tlr")
int threadLocalRandomProbe;
//从公共ThreadLocalRandom序列中分离出的次要种子
@sun.misc.Contended("tlr")
int threadLocalRandomSecondarySeed;
Thread类构造方法
//init(null, null, "Thread-" + nextThreadNum(), 0);
//无参构造 调用init方法设置线程属性
public Thread();
//init(null, target, "Thread-" + nextThreadNum(), 0);
//Runnable target 需要线程执行的代码
public Thread(Runnable target);
// init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
// Runnable target 需要线程执行的代码
// AccessControlContext acc 访问控制上下文
Thread(Runnable target, AccessControlContext acc);
// init(group, target, "Thread-" + nextThreadNum(), 0);
// ThreadGroup group 线程组
// Runnable target 需要线程执行的代码
public Thread(ThreadGroup group, Runnable target);
// init(null, null, name, 0);
// String name 线程名称
public Thread(String name);
// init(group, null, name, 0);
// ThreadGroup group 线程组
// String name 线程名称
public Thread(ThreadGroup group, String name);
// init(null, target, name, 0);、
// Runnable target 需要线程执行的代码
// String name 线程名称
public Thread(Runnable target, String name);
// init(group, target, name, 0);
// ThreadGroup group 线程组
// Runnable target 需要线程执行的代码
// String name 线程名称
public Thread(ThreadGroup group, Runnable target, String name)
//init(group, target, name, stackSize);
// ThreadGroup group 线程组
// Runnable target 需要线程执行的代码
// String name 线程名称
// long stackSize 栈大小
public Thread(ThreadGroup group, Runnable target, String name,long stackSize)
通过源码发现 Thread 类的构造方法调用了 init 方法,此时再来看看 init 方法
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
//线程名称为空时抛出 NullPointerException
if (name == null) {
throw new NullPointerException("name cannot be null");
}
//设置线程名称
this.name = name;
//获取当前正在执行的线程实例
Thread parent = currentThread();
//Java安全管理器SecurityManager
//安全管理器是一个允许应用程序实现安全策略的类。它允许应用程序在执行一个可能不安全或敏感的操作前确定该操作是什么,以及是否是在允许执行该操作的安全上下文中执行它。应用程序可以允许或不允许该操作
SecurityManager security = System.getSecurityManager();
//没有指定线程组时,从SecurityManager中或是Thread parent中获取线程组
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
// 检查是否具有修改线程组的权限
g.checkAccess();
/*
* security不为空时检查权限
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
//增加线程组中未启动线程的计数
g.addUnstarted();
//设置线程实例的线程组
this.group = g;
//将parent线程实例中的daemon变量赋值给当前线程实例
this.daemon = parent.isDaemon();
//将parent线程实例中的priority变量赋值给当前线程实例
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;
//设置线程id
tid = nextThreadID();
}
在init方法里面设置了线程的基本属性
Thread类native方法
//返回对当前正在执行的线程对象的引用
public static native Thread currentThread();
/**
线程让步 当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行,注意是让自己或者其他线程运行,并不是单纯的让给其他线程
它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!
*/
public static native void yield();
/**
使当前正在执行的线程在指定的毫秒数内进入睡眠状态(暂时停止执行),具体取决于系统计时器和调度程序的精度和准确性。线程不会失去任何监视器的所有权
*/
public static native void sleep(long millis) throws InterruptedException;
//启动新的线程运行run方法
private native void start0();
//
private native boolean isInterrupted(boolean ClearInterrupted);
//测试此线程是否仍然存在。如果一个线程已经启动并且尚未死亡,则该线程是活动的
public final native boolean isAlive();
//计算此线程中的堆栈帧数。线程必须被挂起
//此方法已经废弃
public native int countStackFrames();
//当且仅当当前线程在指定对象上持有*监视器锁时,才返回true 此方法旨在允许程序断言当前线程已持有指定的锁
public static native boolean holdsLock(Object obj);
//获取线程堆栈信息
private native static StackTraceElement[][] dumpThreads(Thread[] threads);
//获取所有的线程实例
private native static Thread[] getThreads();
//设置线程的优先级
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);
Thread类内部类
-
Caches
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<>(); }
-
State
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,/** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */ RUNNABLE, /** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {@link Object#wait() Object.wait}. */ BLOCKED, /** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: * <ul> * <li>{@link Object#wait() Object.wait} with no timeout</li> * <li>{@link #join() Thread.join} with no timeout</li> * <li>{@link LockSupport#park() LockSupport.park}</li> * </ul> * * <p>A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called <tt>Object.wait()</tt> * on an object is waiting for another thread to call * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on * that object. A thread that has called <tt>Thread.join()</tt> * is waiting for a specified thread to terminate. */ WAITING, /** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: * <ul> * <li>{@link #sleep Thread.sleep}</li> * <li>{@link Object#wait(long) Object.wait} with timeout</li> * <li>{@link #join(long) Thread.join} with timeout</li> * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> * </ul> */ TIMED_WAITING, /** * Thread state for a terminated thread. * The thread has completed execution. */ TERMINATED; }
-
UncaughtExceptionHandler
@FunctionalInterface public interface UncaughtExceptionHandler { /** * Method invoked when the given thread terminates due to the * given uncaught exception. * <p>Any exception thrown by this method will be ignored by the * Java Virtual Machine. * @param t the thread * @param e the exception */ void uncaughtException(Thread t, Throwable e); }
-
WeakClassKey
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; } /** * Returns true if the given object is this identical * WeakClassKey instance, or, if this object's referent has not * been cleared, if the given object is another WeakClassKey * instance with the identical non-null referent as this one. */ @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; } } }
Thread类常用方法
-
start()
public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ 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 */ } } }
-
interrupt()
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(); }
-
join()
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; } } }
时间不够,后面继续补充