jdk8源码阅读-1.4-java.lang.Thread

本文详细介绍了Java中的线程概念,包括线程的优先级设定、守护线程的特性,以及Java虚拟机如何启动和管理线程。重点讲解了通过继承Thread类和实现Runnable接口创建线程的方式,并剖析了Thread类和Runnable接口的内部实现和方法作用。
摘要由CSDN通过智能技术生成

线程是程序中的执行线程。Java虚拟机允许应用程序同时运行多个执行线程。

每个线程都有一个优先级。优先级高的线程优先于优先级低的线程执行。每个线程可能也可能不被标记为守护进程。当在某个线程中运行的代码创建一个新的thread对象时,新线程的优先级初始设置等于创建线程的优先级,并且当且仅当创建线程是守护线程时,它是守护线程。

当Java虚拟机启动时,通常只有一个非守护线程(它通常调用某个指定类的名为main的方法)。Java虚拟机将继续执行线程,直到出现以下任一情况:1.已经调用了Runtime的退出方法,并且安全管理器允许执行退出操作。2.所有不是守护线程的线程都已死亡,要么从对run方法的调用返回,要么抛出在run方法之外传播的异常。

不同于传统说法一共有三种创建线程的方式,官方文档说明是有两种方法可以创建新的执行线程。1.继承Thread类;2.实现Runnable接口

根据Thread State枚举,分为六种状态:

  • 【NEW】线程刚被创建,但是还没有调用 start() 方法
  • 【RUNNABLE 】当调用了 start() 方法之后,注意,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的
    • 【可运行状态】、【运行状态】和【阻塞状态】(由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为 是可运行)
  • 【BLOCKED】 , 【WAITING】 , 【TIMED_WAITING 】都是 Java API 层面对【阻塞状态】的细分
  • 【TERMINATED 】当线程代码运行结束

一.Thread类实现了Runnable接口

Runnable接口应由任何其实例由线程执行的类实现。 该类必须定义一个名为run的无参数的方法。此接口旨在为希望在活动时执行代码的对象提供通用协议。Runnable由类Thread实现。 活动只是意味着一个线程已经启动但尚未停止。

Runnable接口中只有一个run()方法,它为非Thread类子类的类提供的一种激活方式。一个类实现Runnable接口后,并不代表

该类是一个“线程”类,不能直接运行,必须通过Thread实例才能创建并运行线程。

二.静态变量

  1. int threadInitNumber;为匿名线程自动编号。
  2. long threadSeqNumber;用于生成线程ID
  3. int MIN_PRIORITY = 1;线程最低优先级
  4. int NORM_PRIORITY = 5;线程默认优先级
  5. int MAX_PRIORITY = 10;线程最高优先级
  6. StackTraceElement[] EMPTY_STACK_TRACE= new StackTraceElement[0];

三.静态方法

  1. private static native void registerNatives();将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦。
  2. synchronized int nextThreadNum():为线程编号+1,用synchronized保证线程安全
  3. synchronized long nextThreadID():++threadSeqNumber
  4. native Thread currentThread();返回当前正在执行的线程对象的引用。native,本地方法
  5. native void yield();给调度器的提示,表明当前线程愿意放弃当前对处理器的使用。调度器可以自由地忽略此提示。调用yield方法会让当前线程从Running进入Runnable状态,然后调度执行其他同优先级的线程。如果这时没有其他同优先级的线程,那么不能保证让当前线程暂停的效果
  6. native void sleep(long millis):使当前执行的线程在指定的毫秒数内休眠(暂时停止执行),调用sleep会让当前线程从Running进入Timed Waiting状态
  7. void sleep(long millis, int nanos):与Object类的wait方法的参数类似,nanos的实际效果是将millis+1,然后调用6
  8. boolean interrupted():测试当前线程是否已中断。此方法清除线程的中断状态。
  9. int activeCount():返回当前线程的线程组及其子组中活动线程数的估计值。递归地遍历当前线程的线程组中的所有子组。
  10. int enumerate(Thread tarray[]):将当前线程的线程组及其子组中的每个活动线程复制到指定数组中。这个方法只是调用当前线程的线程组的ThreadGroup.enumerate(Thread[])方法。
  11. void dumpStack():将当前线程的堆栈跟踪信息打印到标准错误流。此方法仅用于调试。
  12. Map<Thread, StackTraceElement[]> getAllStackTraces():返回所有活动线程的堆栈跟踪映射。
  13. boolean isCCLOverridden(Class<?> cl):验证这个(可能是子类)实例可以在不违反安全约束的情况下构造:子类不能覆盖安全敏感的非final方法
  14. boolean auditSubclass(final Class<?> subcl):对给定的子类执行反射检查,以验证它没有覆盖对安全敏感的非final方法。

四.实例变量

  1. volatile String name;线程的名称,volatile关键字修饰可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存
  2. int priority;线程优先级
  3. Thread threadQ:(没找到资料)
  4. long eetop:JVM中的JavaThread指针
  5. boolean single_step;经典VM使用字段single_step来启用或禁用正在运行的线程的单步执行。未由HotSpot采用,并且在jdk11已经删除
  6. boolean daemon = false;表明该线程是否是一个守护线程,默认为false
  7. boolean stillborn = false;JVM状态
  8. Runnable target;用来引用构造函数中传递的Runnable参数,表示线程执行的代码
  9. ThreadGroup group;线程所属的线程组
  10. ClassLoader contextClassLoader;线程用的上下文类加载器,该上下文类加载器可供线程加载类和资源
  11. AccessControlContext inheritedAccessControlContext;继承了这个线程的AccessControlContext
  12. ThreadLocal.ThreadLocalMap threadLocals = null;与线程局部变量相关
  13. ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;与线程局部变量相关
  14. long stackSize;线程的堆栈大小,如果创建者没有指定堆栈大小,则为0。
  15. long nativeParkEventPointer;本机线程终止后仍然存在的vm私有状态。
  16. long tid;线程ID
  17. volatile int threadStatus = 0;线程状态
  18. volatile Object parkBlocker;用于LockSupport.park(Object)方法中,用于引用该方法参数
  19. volatile Interruptible blocker;线程在执行可中断IO操作时阻塞该线程的对象,线程的中断状态被设置后blocker的interrupt方法会被调用
  20. final Object blockerLock = new Object();设置上述blocker变量时用的锁

五.实例方法

  1. void blockedOn(Interruptible b):初始化blocker属性,用blockerLock上锁
  2. void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals):初始化一个线程。就是给线程各变量赋初值的过程
  3. Object clone():因为线程不能被有意义地克隆,内部抛出CloneNotSupportedException。应该使用构建新线程的方式代替此方法
  4. synchronized void start():该线程开始执行;Java虚拟机调用这个线程的run方法。结果是两个线程并发运行:当前线程(从调用start方法返回)和另一个线程(执行其run方法)。首先会对线程状态进行检查,只有0(NEW)状态的才能进行下一步,之后会用try-finally块调用5进行线程的启动
  5. native void start0();cpp底层去寻找并启动当前线程类的run方法
  6. void run():如果这个线程是用一个单独的Runnable run对象构造的,那么这个Runnable对象的run方法将被调用;否则,此方法不做任何事情并返回。继承Thread类来构建线程时应该重写此方法
  7. void exit():这个方法由系统调用,让线程在实际退出之前有机会进行清理。将该线程的变量置空
  8. void stop():强制线程停止执行。有@Deprecated注解,表明不建议使用并在之后的版本可能废弃。底层调用本地方法stop0();
  9. synchronized void stop(Throwable obj):抛出UnsupportedOperationException()异常
  10. void interrupt():中断这个线程。除非当前线程正在中断自己,否则将调用该线程的checkAccess方法,这可能导致抛出SecurityException。如果这个线程在Object类的wait()、wait(long)或wait(long, int)方法的调用中被阻塞,或者在该类的join()、join(long)、join(long, int)、sleep(long)或sleep(long, int)方法的调用中被阻塞,那么它的中断状态(打断标记)将被清除,它将接收一个InterruptedException异常。
  11. boolean isInterrupted():测试此线程是否已中断。此方法不影响线程的中断状态。
  12. native boolean isInterrupted(boolean ClearInterrupted);测试某些线程是否已中断。根据传递的ClearInterrupted的值,是否重置中断状态。
  13. void destroy():抛出NoSuchMethodError()异常,有@Deprecated注解
  14. native boolean isAlive();测试此线程是否处于活动状态。如果一个线程已经启动并且还没有死亡,那么它就是活的。
  15. void suspend():挂起这个线程。首先,调用该线程的checkAccess方法时不带参数。这可能导致抛出SecurityException(在当前线程中)。如果线程是活的,它将被挂起,并且除非它被恢复,否则不会再进行任何操作。有@Deprecated注解
  16. void resume():恢复挂起的线程。首先,调用该线程的checkAccess方法时不带参数。这可能导致抛出SecurityException(在当前线程中)。如果线程是活的,但是挂起了,那么它将被恢复并允许在执行过程中继续进行。
  17. native int countStackFrames();对该线程中的堆栈帧数进行计数。这个线程必须挂起来。有@Deprecated注解
  18. synchronized void join(long millis):等待该线程死亡的时间最多为毫秒。超时为0表示永远等待。底层通过死循环来进行等待的效果
  19. void setDaemon(boolean on):将此线程标记为守护线程或用户线程。当唯一运行的线程都是守护线程时,Java虚拟机退出。此方法必须在线程启动之前调用。
  20. void checkAccess():确定当前运行的线程是否具有修改此线程的权限。在大部分的线程操作里基本都会调用该方法
  21. StackTraceElement[] getStackTrace():由安全管理器抛出,以指示安全违规。
  22. 除以上方法外,还有一些用于获取和设置变量的get,set方法

六.构造器

由于构造器会用到实例方法2,因此定义在下方。Thread类的构造器参数丰富,但是底层都是调用实例方法2来对各变量赋值,未传参数用默认值代替

七.内部类

Caches:有两个静态变量

  1. ConcurrentMap<WeakClassKey,Boolean> subclassAudits =new ConcurrentHashMap<>();子类安全审计结果的缓存
  2. ReferenceQueue<Class<?>> subclassAuditsQueue =new ReferenceQueue<>();被审计子类的WeakReferences队列

八.接口

  1. UncaughtExceptionHandler:用于线程因未捕获异常而突然终止时调用的处理程序。有@FunctionalInterface注解。
  2. void uncaughtException(Thread t, Throwable e);当给定线程因给定未捕获异常而终止时调用。此方法抛出的任何异常都将被Java虚拟机忽略。

九.注解

  1. @CallerSensitive:jdk内有些方法,jvm的开发者认为这些方法危险,不希望开发者调用,就把这种危险的方法用 @CallerSensitive修饰,并在“jvm”级别检查。
  2. @Deprecated:表示此方法已废弃、暂时可用,但以后此类或方法都不会再更新、后期可能会删除,建议后来人不要调用此方法。
  3. @FunctionalInterface:这个接口就可以作为“函数类型”,可以接收一段以Lambda表达式,或者方法引用予以承载的逻辑代码。

除了上述列出的变量,方法之外,还有一些未列出,除去简单的get和set方法外,还有一些没有读懂。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值