Java中Thread源码剖析
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!
关于线程,用很长时间了,主线程下的子线程去做一些事情,就是一个代理模式,主线程分代理权给子线程,子线程帮主线程完成一些任务。
线程的方法大部分都是使用Native使用,不允许应用层修改,是CPU调度的最基本单元。实现线程的方式有三种:使用内核线程、用户线程和混合线程来实现,奉行先行发生的原则。
内核线程:每个生成的线程,都1:1配比一个内核线程来支持,即双线程机制,消耗一个内核资源,类似手机中应用进程
用户线程:普通线程,高速且低耗,创建、切换、调度等问题都需要自己处理
混合实现:降低被阻塞的风险,用户线程与内核线程相当于M:N的关系
线程的调度方式主要有两种:协同式和抢占式,前者简单但不可控制,一个线程执行完通知另外一个;抢占式可以通过yield方法让出执行时间,Java目前就采用这种,同时可以使用设置优先级的方式来提前线程执行顺序,但有可能被“系统”关闭。
今天我们来看下线程的源码,进行系统的学习。
1、首先线程有六种状态
public enum State {
/**
* The thread has been created, but has never been started.
*/
NEW,
/**
* The thread may be run.
*/
RUNNABLE,
/**
* The thread is blocked and waiting for a lock.
*/
BLOCKED,
/**
* The thread is waiting.
*/
WAITING,
/**
* The thread is waiting for a specified amount of time.
*/
TIMED_WAITING,
/**
* The thread has been terminated.
*/
TERMINATED
}NEW:刚创建还没启动
RUNNABLE:可以执行
BLOCKED:堵塞状态,等待持有锁
WAITING :处理等待状态
TIMED_WAITING:等待一些时间
TERMINATED:终止
/**
* The maximum priority value allowed for a thread.
*/
public static final int MAX_PRIORITY = 10;/**
* The minimum priority value allowed for a thread.
*/
public static final int MIN_PRIORITY = 1;/**
* The normal (default) priority value assigned to threads.
*/
public static final int NORM_PRIORITY = 5;2、分别是线程可设置的最大、最小和默认优先级,级别越高执行越靠前
/**
* Holds the thread's ID. We simply count upwards, so
* each Thread has a unique ID.
*/
private long id;3、每个线程都有一个独一无二的ID
public Thread() {
create(null, null, null, 0);
}private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
Thread currentThread = Thread.currentThread();
if (group == null) {
group = currentThread.getThreadGroup();
}if (group.isDestroyed()) {
throw new IllegalThreadStateException("Group already destroyed");
}this.group = group;
synchronized (Thread.class) {
id = ++Thread.count;
}if (threadName == null) {
this.name = "Thread-" + id;
} else {
this.name = threadName;
}this.target = runnable;
this.stackSize = stackSize;this.priority = currentThread.getPriority();
this.contextClassLoader = currentThread.contextClassLoader;
// Transfer over InheritableThreadLocals.
if (currentThread.inheritableValues != null) {
inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
}
// add ourselves to our ThreadGroup of choice
this.group.addThread(this);
}4、初始化一个空的线程,获得当前运行的线程群组,设置id,name,执行线程runnable,池大小stackSize,优先级,并加入到线程群组,这是一个无参的Thread,正常情况下应该有ThreadGroup、Runnable、threadName和stackSize这四个参数。一般threadName如果为空,则报出NullPointerException,stackSize默认为0。
/**
* Destroys the receiver without any monitor cleanup.
*
* @deprecated Not implemented.
*/
@Deprecated
public void destroy() {
throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize???
}5、destroy方法在java7已经被抛弃。
public void interrupt() {
synchronized (interruptActions) {
for (int i = interruptActions.size() - 1; i >= 0; i--) {
interruptActions.get(i).run();
}
}VMThread vmt = this.vmThread;
if (vmt != null) {
vmt.interrupt();
}
}6、停止当前线程,如果线程处于wait、join、sleep状态的线程,会报异常。
public final boolean isAlive() {
return (vmThread != null);
}7、线程是否死掉,主要是判断虚拟机线程有没有死掉VMThread,当然获得当前线程也是通过VMThread.currentThread(),以及接下下获得当前线程处于六大状态中的哪种。
public State getState() {
// TODO This is ugly and should be implemented better.
VMThread vmt = this.vmThread;// Make sure we have a valid reference to an object. If native code
// deletes the reference we won't run into a null reference later.
VMThread thread = vmThread;
if (thread != null) {
// If the Thread Object became invalid or was not yet started,
// getStatus() will return -1.
int state = thread.getStatus();
if(state != -1) {
return VMThread.STATE_MAP[state];
}
}
return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
}public final void join() throws InterruptedException {
VMThread t = vmThread;
if (t == null) {
return;
}synchronized (t) {
while (isAlive()) {
t.wait();
}
}
}8、join堵塞当前线程,使其处于等待状态,因为子线程执行的时间可能比主线程执行时间还长,所以join是主线程需要在它执行完后再销毁。当然也可以加参数join(long millis, int nanos),使其等待N秒N毫秒,如果它已经处于join方法,则报InterruptedException 。
public final void setDaemon(boolean isDaemon) {
if (hasBeenStarted) {
throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
}if (vmThread == null) {
daemon = isDaemon;
}
}9、设置为守护线程,必须的runnable执行前设置,会在其他已经没有非守护线程运行的时候执行。
public final void setPriority(int priority) {
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException("Priority out of range"); // TODO Externalize?
}if (priority > group.getMaxPriority()) {
priority = group.getMaxPriority();
}this.priority = priority;
VMThread vmt = this.vmThread;
if (vmt != null) {
vmt.setPriority(priority);
}
}10、优先级主要通过VMThread来设置的,注意最高设为10最低为1,否则报 IllegalArgumentException。
public static void sleep(long millis, int nanos) throws InterruptedException {
VMThread.sleep(millis, nanos);}
11、执行sleep,如果在sleep期间被interrupt,会报InterruptedException。
/**
* Starts the new Thread of execution. The <code>run()</code> method of
* the receiver will be called by the receiver Thread itself (and not the
* Thread calling <code>start()</code>).
*
* @throws IllegalThreadStateException if the Thread has been started before
*
* @see Thread#run
*/
public synchronized void start() {
if (hasBeenStarted) {
throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
}hasBeenStarted = true;
VMThread.create(this, stackSize);
}12、线程开始执行,如果start已经执行,则报IllegalThreadStateException
@Deprecated
public final synchronized void stop(Throwable throwable) {
throw new UnsupportedOperationException();
}13、stop方法弃用
public static void yield() {
VMThread.yield();
}14、给另一个准备运行的线程让路,让它先执行
关于join和yield的区别,更在上一节:
Java中join和yield的作用
Java中Thread源码剖析的更多相关文章
- 【java集合框架源码剖析系列】java源码剖析之TreeSet
本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...
- 【java集合框架源码剖析系列】java源码剖析之HashSet
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...
- 【java集合框架源码剖析系列】java源码剖析之TreeMap
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于TreeMap的知识. 一TreeMap的定义: public class TreeMap&l ...
- 【java集合框架源码剖析系列】java源码剖析之ArrayList
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 本博客将从源码角度带领大家学习关于ArrayList的知识. 一ArrayList类的定义: public class Arr ...
- 【java集合框架源码剖析系列】java源码剖析之LinkedList
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 在实际项目中LinkedList也是使用频率非常高的一种集合,本博客将从源码角度带领大家学习关于LinkedList的知识. ...
- 【java集合框架源码剖析系列】java源码剖析之HashMap
前言:之所以打算写java集合框架源码剖析系列博客是因为自己反思了一下阿里内推一面的失败(估计没过,因为写此博客已距阿里巴巴一面一个星期),当时面试完之后感觉自己回答的挺好的,而且据面试官最后说的这几 ...
- 我的书籍《深入解析Java编译器:源码剖析与实例详解》就要出版了
一个十足的技术迷,2013年毕业,做过ERP.游戏.计算广告,在大公司呆过,但终究不满足仅对技术的应用,在2018年末离开了公司,全职写了一本书<深入解析Java编译器:源码剖析与实例详解> ...
- 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法
注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...
- Java中ArrayList源码分析
一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保 ...
随机推荐
- 解决HMC在IE浏览器无法登录的问题(Java Applet的使用问题)
管理IBM的小型机必须要用到HMC(Hardware Management Console),有时候在使用测试环境使用的时候我们会把HMC装到自己电脑上的虚拟机里面,然后管理小型机,但是在虚拟机里面使 ...
- sysctl---内核参数相关设置
sysctl命令被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中.它包含一些TCP/ip堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性能 ...
- 浅析[分块]qwq
首先说明这篇博客写得奇差无比 让我们理清一下为什么要打分块,在大部分情况下,线段树啊,splay,treap,主席树什么的都要比分块的效率高得多,但是在出问题的时候如果你和这些数据结构只是混的脸熟的话 ...
- Android向unity发送消息
有些时候需要Android向unity发送消息,有两种方法实现,一.通过unity再带的消息机制,二.通过注册回调的方式. 一.通过UnityPlayer.UnitySendMessage():方法 ...
- Android导航Tab栏实现
前言 android中滑动控件非常多,相信大部分同学接触的都是ListView这样的竖向滑动的控件,可是有时候我们也有横向滑动的需求,非常多应用眼下也做成了这个样子,以weiciyuan为例,例如以下 ...
- 在kettle中实现数据验证和检查
在kettle中实现数据验证和检查 在ETL项目,输入数据通常不能保证一致性.在kettle中有一些步骤能够实现数据验证或检查.验证步骤能够在一些计算的基础上验证行货字段:过滤步骤实现数据过滤:jav ...
- android 视频开发2分之2(仿美拍,糗百)
上一篇写了分段录制和合并视频.这一篇则是选择视频,然后截断视频. 1.从sdcard中找到视频资源: 2.分析视频,拿到你须要的帧数当你的图片.(我的是依据參数来算的多少秒1帧的图片,通常是1秒1帧来 ...
- ajax --- Ajax跨域请求保证同一个session的问题
我们知道,根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务 ...
- Android使用token维持登陆状态的方法
什么是token token(令牌)是一串唯一的字符串,通常由服务端生成,在注册完成时返回给客户端,用来标识此用户,客户端将此字符串存储在本地.在以后的网络请求时,客户端先查询本地的token,如果有 ...
- 2017-2018年红头发新版Cisco认证网络工程师(CCNA-R&S)全新讲解分享
网名"红头发",多年授课经验,业内资深思科认证讲师,其所写的CISCO认证原创技术文章风靡各大网站与培训机构.精通CISCO各类路由交换产品,熟悉JUNIPER M/T系列路由产品 ...