【Java源码解析】Thread
简介
线程本质上也是进程。线程机制提供了在同一程序内共享内存地址空间运行的一组线程。对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间。在Java语言里,Thread类封装了线程相关的特性,使用其进行多线程编程。
源码解析
线程状态
public enum State {
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;
}
认识3个队列
- threadScheduleQueue,线程调度队列,操作系统根据此队列给每个线程分配CPU时间片
- synchronousQueue,同步队列,多个线程争用同一把锁时,未抢到锁的线程会在此队列里等待
- conditionQueue,条件队列,抢到锁的线程要等待某个条件而释放锁就会进入此队列里被别的拿到锁的线程唤醒。
三个队列的关系
一个线程自创建起,一定是先被安排进入threadScheduleQueue,轮到它的时间片投入运行,遇见临界区,抢锁失败后会进入synchronousQueue,可能 要等待某个条件,继而进入conditionQueue,
如果别的线程唤醒它,离开conditionQueue,进入synchronousQueue,继续抢占锁,执行完同步代码块,最后回到threadScheduleQueue,等待下次被调度。
线程状态
- NEW,线程刚刚创建,尚未启动
- RUNNABLE,可运行,此时线程在threadScheduleQueue
- BLOCKED,阻塞(在某把锁上),此时线程在synchronousQueue
- WAITING,等待某个条件,此时线程在conditionQueue
- TIMED_WAITING,带超时的WAITING
- TERMINATED,线程终止
线程状态转换
属性
private volatile char name[]; // 线程名称
private int priority; // 优先级
private Thread threadQ;
private long eetop;
private boolean single_step; // 是否单步执行
private boolean daemon = false; // 是否是守护线程
private boolean stillborn = false;
private Runnable target; // 目标任务
private ThreadGroup group; // 线程组
private ClassLoader contextClassLoader; // 上下文类加载器
private AccessControlContext inheritedAccessControlContext; // 继承的访问控制上下文
private static int threadInitNumber; // 线程编号 private static synchronized int nextThreadNum() {
return threadInitNumber++;
} ThreadLocal.ThreadLocalMap threadLocals = null; // 线程本地变量Map
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; // 线程本地变量Map,会继承父线程的变量初始值
private long stackSize; // 该线程请求的堆栈大小
private long nativeParkEventPointer;
private long tid; // 线程ID
private static long threadSeqNumber; // 用来生成线程ID
private volatile int threadStatus = 0; // 线程状态 private static synchronized long nextThreadID() {
return ++threadSeqNumber;
} volatile Object parkBlocker; // 中断阻塞器
private volatile Interruptible blocker;
private final 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; // 最大优先级
构造方法
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);
} 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方法。
init()
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name.toCharArray(); // 线程名称
Thread parent = 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(); // 继承父线程的daemon属性
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 (parent.inheritableThreadLocals != null) // 如果父线程的可继承线程变量不为空,则传递给子线程
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
this.stackSize = stackSize;
tid = nextThreadID(); // 设置线程ID
}
start()
public synchronized void start() {
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) {
}
}
} private native void start0();
interrupt()
public void interrupt() {
if (this != Thread.currentThread())
checkAccess(); synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // 设置中断标记
b.interrupt(this);
return;
}
}
interrupt0();
} private native void 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); // 调用object的wait()方法
}
} else {
while (isAlive()) { // 带超时的join
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay); // 调用object的wait()方法
now = System.currentTimeMillis() - base;
}
}
}
行文至此结束。
尊重他人的劳动,转载请注明出处:http://www.cnblogs.com/aniao/p/aniao_thread.html
【Java源码解析】Thread的更多相关文章
- Java源码解析——集合框架(三)——Vector
Vector源码解析 首先说一下Vector和ArrayList的区别: (1) Vector的所有方法都是有synchronized关键字的,即每一个方法都是同步的,所以在使用起来效率会非常低,但是 ...
- Java源码解析——集合框架(二)——ArrayBlockingQueue
ArrayBlockingQueue源码解析 ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection ...
- [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析
String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, ...
- [java源码解析]对HashMap源码的分析(二)
上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得“拉链法 ...
- java源码解析之Object类
一.Object类概述 Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解 Object的方法可以分成两类,一类是被关键字fin ...
- Java源码解析——Java IO包
一.基础知识: 1. Java IO一般包含两个部分:1)java.io包中阻塞型IO:2)java.nio包中的非阻塞型IO,通常称为New IO.这里只考虑到java.io包中堵塞型IO: 2. ...
- java源码解析
String深入解析 String具有不变性的原因: String被final修饰,它不可能被继承,也就是任何对String的操作方法,都不会被继承覆写 String中保存数据的是一个char数组的v ...
- java源码解析——Stack类
在java中,Stack类继承了Vector类.Vector类和我们经常使用的ArrayList是类似的,底层也是使用了数组来实现,只不过Vector是线程安全的.因此可以知道Stack也是线程安全的 ...
- 【Java源码解析】ThreadLocal
简介 线程本地变量,用于同一线程之间的传递.每一个线程对象都保存在两个ThreadLocalMap,threadLocals和inheritableThreadLocals,后者会继承父线程的本地变量 ...
随机推荐
- 数组(list)分组、分段
对一个list进行分组,要求控制每组中的元素个数: 1.使用切片分组: lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1] #lst可为 ...
- html5 js 游戏的一篇博客 貌似不错
http://blog.csdn.net/lufy_legend/article/details/8888787
- 【笔记】python的sqlalchemy数据库连接池原理的说明
sqlalchemy数据库连接池的使用方式是延迟初始化,就是说一开始你调用create_engine(...)后创建的那个数据库池是空的,你后面通过session.connection()或者engi ...
- 51nod 1444 破坏道路(bfs+枚举)
1444 破坏道路 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 在某一个国家,那儿有n个城市,他们通过m条双向 ...
- Java8系列之重新认识HashMap(转)
原文出处: 前利 简介 Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap.Hashtable.LinkedHashMap和Tree ...
- Linux配置CentOs7.4(网络连接处理)
说明:CentOS 7.0默认安装好之后是没有自动开启网络连接的! 进入登录界面 账号输入root 回车 再输入上面设置的root密码回车 系统登录成功 设置IP地址.网关DNS cd /etc/s ...
- 2668: [cqoi2012]交换棋子
Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...
- Day3 MySql高级查询
DQL高级查询 多表查询(关联查询.连接查询) 1.笛卡尔积 emp表15条记录,dept表4条记录. 连接查询的笛卡尔积为60条记录. 2.内连接 不区分主从表,与连接顺序无关.两张表均满足条件则出 ...
- vux UI 项目国际化
第一步必须装 vux vux-loader vuex 和vuex-i18n npm i vux-loader -D npm i vuex vux vuex-i18n -S 安装完成需要配置webpac ...
- Python高级编程和异步IO并发编程
第1章 课程简介介绍如何配置系统的开发环境以及如何加入github私人仓库获取最新源码. 1-1 导学 试看 1-2 开发环境配置 1-3 资源获取方式第2章 python中一切皆对象本章节首先对比静 ...