多线程源码--Thread源码
Posted fondwang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程源码--Thread源码相关的知识,希望对你有一定的参考价值。
前言
Java.lang.Thread是Java应用程序员对Java多线程的第一站,Thread就是对Java线程本身的抽象
所以在Java中的线程编程概念中,一个Thread实例 == 一个线程
线程有哪些属性、行为,Thread大致就有哪些属性、行为。
源码
构造器
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); }
Thread(Runnable target, AccessControlContext acc) { init(null, target, "Thread-" + nextThreadNum(), 0, acc, false); }
从上面可以看出,所有的构造器都依赖着init方法
private void init(ThreadGroup g, Runnable target, String name,long stackSize)
除了上面列表的最后一个构造器外,其他构造器传递的参数,都在上面 init() 方法参数只能。这几个参数的解释如下:
ThreadGroup 线程组;
Runnable 封装线程任务;
String name 线程名称;
long stackSize 虚拟机栈的空间大小,默认为0,不设置 即忽略它。
现在来说说与构造器相关的 init() 方法源码
由上图可见,大多数构造器(就是除上面最后一个),都是先将数据传递上图第一个init方法,然后内部再次调用它的重载方法。我们来看看这个方法源码
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(); //父线程,currentThread()是个本地方法,意思是这个线程的父线程是正在运行的线程,也就是创建这个线程的线程
SecurityManager security = System.getSecurityManager(); //安全管理器
if (g == null) { //如果线程组为空
//如果安全管理器不为空,则当前线程组就使用管理器指定的线程组
if (security != null) {
g = security.getThreadGroup();
}
//或者使用父线程的线程组
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;
//设置线程ID
tid = nextThreadID();
}
属性
private volatile String name; //线程名称
private int priority; //线程优先级
private Thread threadQ;
private long eetop;
//是否单步执行这个线程。
private boolean single_step;
//是否为守护线程
private boolean daemon = false;
//jvm状态值
private boolean stillborn = false;
//线程任务
private Runnable target;
//线程组
private ThreadGroup group;
//此线程的上下文类装入器
private ClassLoader contextClassLoader;
//它封装的上下文做出系统资源访问决策。
private AccessControlContext inheritedAccessControlContext;
//自动编号。就是当没有设置线程名称的时候。我们看到的Thread-0 Thread-1
private static int threadInitNumber;
private long stackSize; //线程堆栈空间大小,默认0,不用管
//jvm私有状态,在本机线程终止后仍然存在。
private long nativeParkEventPointer;
private long tid; //线程ID
//用于生成线程ID
private static long threadSeqNumber;
private volatile int threadStatus = 0;//线程初始状态。表示线程尚未启动
volatile Object parkBlocker;
private volatile Interruptible blocker;
private final Object blockerLock = new Object();//用于synchronized关键字的实例锁
public final static int MIN_PRIORITY = 1;//最小优先级
public final static int NORM_PRIORITY = 5;//默认优先级
public final static int MAX_PRIORITY = 10;//最大优先级
常用的关键方法
start()启动方法
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) { //什么也不做。如果start0抛出一个投掷物它将被传递到调用堆栈
} } }
private native void start0(); //start0本地方法
run()运行方法
public void run() {
//线程任务不为空时,调用父接口的run方法
if (target != null) {
target.run();
}
}
exit()退出方法
//清除必要的资源
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
target = null;
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
interrupt()中断方法
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();//权限检查
synchronized (blockerLock) {
Interruptible b = blocker; //设置中断接口
if (b != null) {
interrupt0(); // 设置中断标志
b.interrupt(this);
return;
}
}
interrupt0();
}
//interrupt0()是本地方法
interrupted() 是否已中断
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);
线程是否被激活isAlive()
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; }
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 static native void yield(); //暂停一下线程,回到就绪状态
join()方法
public final void join() throws InterruptedException {
join(0); //调用下面的方法
}
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis(); //设置开始时间
long now = 0;
if (millis < 0) { //传递参数小于0,抛异常
throw new IllegalArgumentException("timeout value is negative");
}
//参数为0
if (millis == 0) {
while (isAlive()) { //线程处于运行状态
wait(0); //调用Object的wait方法
}
} else { //如果参数大于0
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) { //当前时间不能大于设置的时间之后的时间
break;
}
wait(delay); //调用Object的wait方法
now = System.currentTimeMillis() - base; //当前时间
}
}
}
public final synchronized void join(long millis, int nanos) throws InterruptedException {
if (millis < 0) { //不可小于0
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) { //纳秒不可超过规定范围
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
//如果纳秒符合条件,秒自增1
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis); //调用上面的方法
}
sleep()方法
public static void sleep(long millis, int nanos) throws InterruptedException {
if (millis < 0) { //参数必须大于0
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) { //纳秒要在规定范围
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
//如果纳秒符合条件,秒自增1
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis); //调用本地方法
}
public static native void sleep(long millis) throws InterruptedException; //本地方法
Daemon相关方法
public final void setDaemon(boolean on) { //设置是否为守护线程
checkAccess(); //权限效验
if (isAlive()) { //当前线程不能为激活状态
throw new IllegalThreadStateException();
}
daemon = on; //设置当前线程是否为守护线程
}
//是否为守护线程
public final boolean isDaemon() {
return daemon;
}
以上就是常用的api源码,个人能力不足,还请见谅,待之后进行完善。
以上是关于多线程源码--Thread源码的主要内容,如果未能解决你的问题,请参考以下文章