简介

线程本质上也是进程。线程机制提供了在同一程序内共享内存地址空间运行的一组线程。对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间。在Java语言里,Thread类封装了线程相关的特性,使用其进行多线程编程。

源码解析

线程状态

     public enum State {
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;
}
认识3个队列
  1. threadScheduleQueue,线程调度队列,操作系统根据此队列给每个线程分配CPU时间片
  2. synchronousQueue,同步队列,多个线程争用同一把锁时,未抢到锁的线程会在此队列里等待
  3. 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

最新文章

  1. Sql 常用时间转换
  2. 用 javascript 脚本,网站判读来访者是手机还是电脑
  3. Etag,Expires与Cache-control
  4. 删除xcode中的描述文件的路径
  5. linux BASH shell设置字体与背景颜色
  6. FIREDAC连接MSSQL 2000报不能支持连接MSSQL2000及更低版本的解决办法
  7. [wikioi]最长严格上升子序列
  8. set排序(个人模版)
  9. 安装mysql后运行.net程序出错
  10. 数组拆分I
  11. vue组件导航栏动态添加class
  12. sqlplus连接远程数据库
  13. 《深入理解JAVA虚拟机》----------第三章 垃圾收集器与内存分配策略,笔记(下)
  14. Python——验证码识别 Pillow + tesseract-ocr
  15. 【Linux技术】autotools制作makefile过程详解
  16. 线程同步 –AutoResetEvent和ManualResetEvent
  17. [one day one question] webpack 打包报错 Cannot assign to read only property &#39;exports&#39; of object &#39;#&lt;Object&gt;&#39;
  18. BLE pairing vs. bonding
  19. 深入理解java集合框架之---------Arraylist集合
  20. 原生js粘贴复制【源码】

热门文章

  1. [翻译] RSKImageCropper
  2. 解决 锁定文件失败 打不开磁盘“D:\ubuntu\Ubuntu 64 位.vmdk”或它所依赖的某个快照磁盘。 模块 Disk”启动失败
  3. Xman资格选拔赛-web
  4. SDN上机第二次作业
  5. impala jdbc驱动执行impala sql的一个坑(不支持多行sql)
  6. Hive学习之路 (十)Hive的高级操作
  7. week6:Diagnosing Bias vs. Variance难点记录
  8. 利用java代码生成keyStore
  9. P1006 传纸条
  10. Apache24 + php5.6.31 +Sql server R2 环境搭建①