JDK源码(20)-Thread
一、概述
此线程指的是执行程序中的线程。 Java虚拟机允许应用程序同时执行多个执行线程。
每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的Thread
对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。
当Java虚拟机启动时,通常有一个非守护进程线程(通常调用某些指定类的名为main
的方法)。 Java虚拟机将继续执行线程,直到发生以下任一情况:
- 已经调用了
Runtime
类的exit
方法,并且安全管理器已经允许进行退出操作。 - 所有不是守护进程线程的线程都已经死亡,无论是从调用返回到
run
方法还是抛出超出run
方法的run
。
创建一个新的执行线程有两种方法。 一个是将一个类声明为Thread
的子类。 这个子类应该重写run
类的方法Thread
。 然后可以分配并启动子类的实例。 例如,计算大于规定值的素数的线程可以写成如下:
class PrimeThread extends Thread {long minPrime;PrimeThread(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}
然后,以下代码将创建一个线程并启动它运行:
PrimeThread p = new PrimeThread(143);p.start();
另一种方法来创建一个线程是声明实现类Runnable
接口。 那个类然后实现了run
方法。 然后可以分配类的实例,在创建Thread
时作为参数传递,并启动。 这种其他风格的同一个例子如下所示:
class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}
然后,以下代码将创建一个线程并启动它运行:
PrimeRun p = new PrimeRun(143);new Thread(p).start();
每个线程都有一个用于识别目的的名称。 多个线程可能具有相同的名称。 如果在创建线程时未指定名称,则会为其生成一个新名称。
除非另有说明,否则将null
参数传递给null
中的构造函数或方法将导致抛出NullPointerException
。
二、属性、内部类和接口
静态枚举类:线程状态
public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;}
Thread.UncaughtExceptionHandler:当Thread由于未捕获的异常而突然终止时,处理程序的接口被调用。
@FunctionalInterfacepublic 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);}
线程的最大、最小、默认优先级。默认为5。
/*** The minimum priority that a thread can have.*/public final static int MIN_PRIORITY = 1;/*** The default priority that is assigned to a thread.*/public final static int NORM_PRIORITY = 5;/*** The maximum priority that a thread can have.*/public final static int MAX_PRIORITY = 10;
三、常用方法
修饰符和返回值 | 方法名称及描述 |
---|---|
static int
|
activeCount()
返回当前线程的thread group及其子组中活动线程数的估计。 |
void
|
checkAccess()
确定当前正在运行的线程是否有权限修改此线程。 |
protected Object
|
clone()
将CloneNotSupportedException作为线程抛出无法有意义地克隆。 |
static Thread
|
currentThread()
返回对当前正在执行的线程对象的引用。 |
static void
|
dumpStack()
将当前线程的堆栈跟踪打印到标准错误流。 |
static int
|
enumerate(Thread[] tarray)
将当前线程的线程组及其子组中的每个活动线程复制到指定的数组中。 |
static Map<Thread,StackTraceElement[]>
|
getAllStackTraces()
返回所有活动线程的堆栈跟踪图。 |
ClassLoader
|
getContextClassLoader()
返回此Thread的上下文ClassLoader。 |
static Thread.UncaughtExceptionHandler
|
getDefaultUncaughtExceptionHandler()
返回当线程由于未捕获异常突然终止而调用的默认处理程序。 |
long
|
getId()
返回此线程的标识符。 |
String
|
getName()
返回此线程的名称。 |
int
|
getPriority()
返回此线程的优先级。 |
StackTraceElement[]
|
getStackTrace()
返回表示此线程的堆栈转储的堆栈跟踪元素数组。 |
Thread.State
|
getState()
返回此线程的状态。 |
ThreadGroup
|
getThreadGroup()
返回此线程所属的线程组。 |
Thread.UncaughtExceptionHandler
|
getUncaughtExceptionHandler()
返回由于未捕获的异常,此线程突然终止时调用的处理程序。 |
static boolean
|
holdsLock(Object obj)
返回 true当且仅当当前线程在指定的对象上保持监视器锁。 |
void
|
interrupt()
中断这个线程。 |
static boolean
|
interrupted()
测试当前线程是否中断。 |
boolean
|
isAlive()
测试这个线程是否活着。 |
boolean
|
isDaemon()
测试这个线程是否是守护线程。 |
boolean
|
isInterrupted()
测试这个线程是否被中断。 |
void
|
join()
等待这个线程死亡。 |
void
|
join(long millis)
等待这个线程死亡最多 |
void
|
join(long millis, int nanos)
等待最多 |
void
|
run()
如果这个线程使用单独的 |
void
|
setContextClassLoader(ClassLoader cl)
设置此线程的上下文ClassLoader。 |
void
|
setDaemon(boolean on)
将此线程标记为 daemon线程或用户线程。 |
static void
|
setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
设置当线程由于未捕获的异常突然终止而调用的默认处理程序,并且没有为该线程定义其他处理程序。 |
void
|
setName(String name)
将此线程的名称更改为等于参数 |
void
|
setPriority(int newPriority)
更改此线程的优先级。 |
void
|
setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
设置当该线程由于未捕获的异常而突然终止时调用的处理程序。 |
static void
|
sleep(long millis)
使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。 |
static void
|
sleep(long millis, int nanos)
导致正在执行的线程以指定的毫秒数加上指定的纳秒数来暂停(临时停止执行),这取决于系统定时器和调度器的精度和准确性。 |
void
|
start()
导致此线程开始执行; Java虚拟机调用此线程的 |
String
|
toString()
返回此线程的字符串表示,包括线程的名称,优先级和线程组。 |
static void
|
yield()
对调度程序的一个暗示,即当前线程愿意产生当前使用的处理器。 |
主要方法的源码:
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 thenit will be passed up the call stack */}}}public void run() {if (target != null) {target.run();}}public void interrupt() {if (this != Thread.currentThread())checkAccess();synchronized (blockerLock) {Interruptible b = blocker;if (b != null) {interrupt0(); // Just to set the interrupt flagb.interrupt(this);return;}}interrupt0();}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 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 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;}}}public final synchronized void join(long millis, int nanos)throws InterruptedException {if (millis < 0) {throw new IllegalArgumentException("timeout value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos >= 500000 || (nanos != 0 && millis == 0)) {millis++;}join(millis);}public final void setDaemon(boolean on) {checkAccess();if (isAlive()) {throw new IllegalThreadStateException();}daemon = on;}public final void checkAccess() {SecurityManager security = System.getSecurityManager();if (security != null) {security.checkAccess(this);}}@CallerSensitivepublic ClassLoader getContextClassLoader() {if (contextClassLoader == null)return null;SecurityManager sm = System.getSecurityManager();if (sm != null) {ClassLoader.checkClassLoaderPermission(contextClassLoader,Reflection.getCallerClass());}return contextClassLoader;}public void setContextClassLoader(ClassLoader cl) {SecurityManager sm = System.getSecurityManager();if (sm != null) {sm.checkPermission(new RuntimePermission("setContextClassLoader"));}contextClassLoader = cl;}
参考资料:
- http://www.matools.com/api/java8
JDK源码(20)-Thread相关推荐
- JDK源码解析 Runable是一个典型命令模式,Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法
JDK源码解析 Runnable是一个典型命令模式, Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法 /命令接口(抽象命令角色) public interfa ...
- 调试JDK源码-ConcurrentHashMap实现原理
调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hash ...
- JDK源码学习路线~每天学一点~每天进步一点点
很多java开发的小伙伴都会阅读jdk源码,然而确不知道应该从哪读起.以下为小编整理的通常所需阅读的源码范围. 标题为包名,后面序号为优先级1-4,优先级递减 1.java.lang 1) Objec ...
- JAVA JDK源码在线阅读
Java的版本是1.8.0_111,我把JDK源码发布到了github上,大家看起来也比较方便,地址: https://github.com/daiqingliang/java_jdk1.8.0_11 ...
- 为什么jdk源码推荐ThreadLocal使用static
ThreadLocal是线程私有变量,本身是解决多线程环境线程安全,可以说单线程实际上没必要使用. 既然多线程环境本身不使用static,那么又怎么会线程不安全.所以这个问题本身并不是问题,只是有人没 ...
- JDK源码研究Jstack,JMap,threaddump,dumpheap的原理
JDK最新bug和任务领取:https://bugs.openjdk.java.net/projects/JDK/issues 参加OpenJDK社区:https://bugs.openjdk.jav ...
- 调试JDK源码-Hashtable实现原理以及线程安全的原因
调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hash ...
- Java是如何实现自己的SPI机制的? JDK源码(一)
注:该源码分析对应JDK版本为1.8 1 引言 这是[源码笔记]的JDK源码解读的第一篇文章,本篇我们来探究Java的SPI机制的相关源码. 2 什么是SPI机制 那么,什么是SPI机制呢? SPI是 ...
- 一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach
一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 代 ...
- 结合JDK源码看设计模式——桥接模式
前言: 在我们还没学习框架之前,肯定都学过JDBC.百度百科对JDBC是这样介绍的[JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Jav ...
最新文章
- 【linux】CentOS启动后网络自动配置过程
- LeetCode 1155. 掷骰子的N种方法(DP)
- GDI+ 透明窗口.UpdateLayeredWindow
- 风投盯上阿里云开发者大会寻下一个阿里
- python invalid character_python提示invalid character in identifier
- opensips1.6.4+freeradius2.1.10+radiusclient0.5.6 problem do accounting
- 思科路由器常用配置命令大全
- php中mbsubstr汉字,php中文字符串截取(mb_substr)实例
- 自己建设网站需要学习什么?
- 你是如何看待saas行业
- ctab提取dna流程图_DNA提取(CTAB法)
- Strategic game poj1463
- 哈希(哈希表的应用)
- 数字电路反相器符号_逻辑非门真值表教程和反相器振荡器等效
- word无法打开文件,因为内容有错误的解决办法
- 分组查询最新的一条记录
- 快速成为抖音内容运营高手的心法
- 陕师大计算机好就业吗,陕师大是好学校吗?陕师大出来好不好就业?
- 2021-2025年中国自攻螺丝行业市场供需与战略研究报告
- oracle数据库led显示屏,LED大屏幕设置软件