十五.Thread类
线程的状态:
- NEW:创建但尚未执行
- RUNNABLE:可执行,或正在执行中.但是也有可能正在等待资源分配(线程资源)
- BLOCKED:阻塞状态,获取需要的对象锁而阻塞.比如在synchronized区块或者方法时被阻塞.
- WAITING:等待状态,比如调用了object/this.wait(),或者其他线程的join(),或者被LockSupport.park(this)
- TIME_WAITING:同WAITING,只是指定了等待时间,比如Thread.sleep(20000)、wait(2000)等。
- TERMINATED: 终止,线程运行结束。需要注意,一个被interrupted的线程并不处于此状态,它仍然可以继续运行,interrupted的标识需要程序自己判定。
我们可以通过“jstack”指令开查看JVM进程的的线程状态。
Thread有几个私有属性需要介绍:
- boolean daemon:是否为守护线程.默认为false,可以在线程启动前,通过setDaemon(boolean)来指定.
- Runnable target:线程需要执行的任务单元,可以通过指定target或者重写run方法的方式运行任务.
- ThreadLocal.ThreadLocalMap threadLocals:当前线程所持有的threadLocalMap,保存ThreadLocal集合.
- ThreadLocal.ThreadLocalMap inheritableThreadLocals:InheritableThreadLocal使用的保存ThreadLocal实例的map
- long stackSize:线程需要的stack大小,可以通过此方式指定当前线程的stack大小,默认0表示使用VM配置的stack大小.部分VM会忽略此参数.stackSize可以通过构造函数来指定,此参数具有高度的平台依赖性.在某些平台上,指定一个较高的stacksize可以避免抛出StackOverflowError,从而使线程具有更深的递归深度.指定一个较低且合理的值,能够允许较多的线程并发的存在(但不能太小,否则overflow).此外,某些平台上,可能指定此参数将没有效果.
- volatile Object parkBlocker:在LockSupport.setBlocker(Thread,Blocker)中指定的对象即LockSupport.park(Blocker),此值将有本地实现修改它.可以通过LockSupport.getBlocker()获取.(无特殊作用,可被用来检测当前线程阻塞的信息)
方法列表:
- public static Thread currentThread():获取当前线程.native方法.
- public static void yield():暂停当前执行的线程对象,并执行其他线程.线程让步并被重新参与调度,避免单个线程长时间消耗系统资源.
- public static void sleep(long):线程休眠(暂停),超时后继续执行,sleep时不会丢失任何监视器的所属权.(区别于wait,wait会原子性释放监视器),需要注意sleep方法会释放CPU资源,线程此后进入阻塞状态,直到超时或者被打断,不过sleep(0)是一种特例。
- public void start():VM分配线程资源(系统资源),使线程开始执行,即处于RUNNABLE状态(status属性).VM会根据调度,适时调用其run()方法.多次启动一个线程非法的,特别是当线程已经结束后,将不能再次被启动,抛出IllegalThreadStateException.
- public void run():任务实际执行单元,start()方法将会间接的调用run方法,如果指定了runnable,则调用runnale的run 方法.否则直接返回.Thread 的子类应该重写该方法,以定制操作..
- public final void stop():已过时,stop方法是一种粗暴的终止线程的方式,它将释放已经锁定的所有监视器.如果此前被监视器持有的同步对象将会处于不一致状态.则损坏的对象对其他线程可见.对象锁获取之后,一个线程可能需要对此对象做多个组合型操作才能对数据的状态修改完成,如果stop将会将正在对象锁释放,产生数据状态不一致(不符合逻辑)的情况.stop线程将会导致一个ThreadDeath异常被记录,Thread实例中有个属性为throwableFromStop,此时将会被赋值..在线程start时,已经再次调度时,会检测throwableFromStop属性是否为null.如果非null,将会把此异常再次抛出.
- public void interrupt():中断线程,目前唯一一种安全的线程中断手段.如果其他线程调用"interrupt"方法,将会导致进行checkAcess进行权限校验(检测当前线程是否有权限中断此线程).如果线程在调用Object.wait或者join或者sleep时被阻塞,则其中断状态将会被清除,此线程将会受到InterruptedException,阻塞被打断.如果该线程在"可中断通道"上进行IO操作(InterruptibleChannel)中阻塞,则该channel将会被关闭,改线程的中断状态将被设置,且改线程将收到ClosedByInterruptException(NIO特性,异步关闭)如果该线程在一个Selector中阻塞(Selector.select()),那么该线程的中断状态将被设置,它将立即返回.
//////////////////////方法内部实现 public void interrupt() { //首先检测当前线程是否自己(其他线程中断,需要检测权限,自己中断自己也是允许的) if (this != Thread.currentThread()) checkAccess(); //blockerLock是Thread的一个内部私有属性,一个无类型的Object,仅仅用来表达锁的情况. synchronized (blockerLock) { //Thread中有个blocker属性,这个属性是用来标记IO操作的同步点..如果NIO正在进行数据read/write,会在当前Thread //实例中注册一个Interruptible实例给Thread.blocker(通过Thread.blockedOn(Interruptible b)方式) //NIO之所以能够响应中断,也是归于此属性. //参见AbstractInterruptibleChannel.begin()/end(boolean completed). //参见AbstractSelector.begin()/end() Interruptible b = blocker; //如果此线程正在处理NIO操作,且注册了Interruptible回调实例 if (b != null) { //标记线程为中断状态 interrupt0(); // Just to set the interrupt flag //回调:此方法将会将NIO操作实例的interrupted属性标记为true,并响应一个异常. //并关闭IO操作. b.interrupt(); return; } } interrupt0();//本地方法,设置线程的中断状态为true. }
如果线程中没有“object.wait()”“Thread.sleep()”等阻塞情况,那么run方法中将无法捕获interruptedException,那么开发者需要在何时的时机判定interrupted标识来决定是否退出线程。
Thread thread = Thread.currentThread(); while (!thread.isInterrupted()) { //do something. }
- public static boolean interrupted():清除中断状态,将中断状态置为false.如果当前线程已经中断,则返回true.否则返回false.
- public static boolean isInterrupted():检测线程的中断状态,此方法不会清除线程中断状态.
- public void destroy():已过时,此方法没有被实现..
- public final boolean isAlive():检测线程是否处于活跃状态.如果线程线程已经被start且没有消亡,返回true.否则返回false.
- public final void suspend():已过时,具有固定的死锁倾向,和resume()匹配操作.
- public final void setPriority(int):设置线程的优先级,此方法会触发checkAccess."优先级"值需要在MIN_PRIORITY和MAX_PRIORITY之间.即1~10.线程调度器有更大的几率会选择优先级较高的线程运行.但不保证优先级高的一定会运行.
- public final void join():线程切入,此操作将阻断当前线程,直到切入者执行完成.(内部实现为指定thread对象的wait方法,当thread执行完毕以后,由此thread线程notify,本地方法实现)
- public final void join(long):线程切入,此操作最大阻塞当前线程指定的时间,超时后,当前线程继续执行,切入者不会被中断.此方法可以抛出InterruptedException.
- public final void checkAccess():基于SecurityManager检测当前运行的线程是否有权限修改线程信息.
- public ClassLoader getContextClassLoader():返回当前线程的上下文ClassLoader.上下文 ClassLoader 由线程创建者提供,供运行于该线程中的代码在加载类和资源时使用。如果未设定,则默认为父线程的 ClassLoader 上下文。原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器。
内部实现: Thread parent = Thread.currentThread(); classLoader = parent.getContextClassLoader() ;//即线程的classLoader有当前线程的创建者线程提供.
不过Thread也提供了setContextClassLoader(ClassLoader),不过此方法会checkAccess.
- public static boolean holdsLock(Object):检测当前线程是否持有对象锁.如果当前线程持有对象监视器,则返回true.默认为native实现.
- public StackTraceElement[] getStackTrace():获取当前线程的堆栈跟踪元素.
十六.ThreadGroup类
ThreadGroup即线程组,线程组是有多个线程的集合.线程组也可以"继承自"其他线程组,可以把线程组维护成树状结构.允许线程访问有关自己的线程组信息,但不允许其访问其他线程组包括父线程组信息.
线程组提供了统一管理线程集合的方法.底层使用数组存储线程组的所有线程.
- ThreadGroup(String name)
- ThreadGroup(ThreadGroup parent,String name):指定父线程.任何Thread实例在创建时都会具有ThreadGroup,即使不指定,也会被系统默认为父线程所属的线程组.所以,Thread.currentThread().getThreadGroup()可以检测当前线程使用的线程组.java应用程序启动,会创建一个main线程组,如果不指定Group则为main线程组(默认线程组).
- public boolean isDestroyed():检测线程组是否已经被销毁.
- public final void setDaemon(boolean daemon):标明此线程组为一个守护线程组.
- public final void interrupt():中断线程组中所有的线程.
- public final void destroy():销毁线程组及其子线程组..此时线程组必须为空,不能包含任何线程.否则将会抛出IllegalThreadStateException .被销毁的ThreadGroup将不能再次被使用.
相关推荐
这份"JAVA全套API手册整理.zip"包含的应该是一份详尽的Java API文档,帮助开发者理解和使用Java平台的各种功能。 Java API涵盖了许多关键领域,包括: 1. **基础类库**:如Object、String、ArrayList、HashMap等,...
根据提供的文件信息,我们可以整理出以下关于Java考试的要点及相关知识点: ### Java考试要点概览 #### 一、Java的历史与发展 - **起源**: Java语言最初由Sun Microsystems公司于1991年开始开发,最初命名为“Oak...
### Robotium 2.5 API 整理及详解 #### 一、概述 Robotium是一款用于Android自动化测试的开源框架,它可以模拟用户操作来进行UI测试。Robotium支持各种类型的测试,包括功能测试、系统测试以及接受性测试等。在...
这份“Java基础知识学习--自己整理.zip”压缩包显然是一个精心整理的Java初学者教程,包含了作者的学习笔记和心得,旨在帮助新手快速入门。下面将详细阐述Java的基础知识。 **一、Java简介** Java是由Sun ...
### Java 常用API的运用、效率及技巧 #### 1. Java 面向对象基本概念 Java 是一种完全面向对象的语言,除了几种基本数据类型(如 int、double 等)之外,所有事物都被视为对象。面向对象编程(OOP)的基本原则包括...
这份资料的核心是“JAVA面试题集编程篇.pdf”,它整理了Java编程领域的常见问题和解答,为面试者提供了一个全面的复习平台。 一、基础概念与语法 1. Java的特性:理解Java的面向对象特性,包括封装、继承、多态。 2...
本资料包"Java常用的插件API整理以及基于JDK的一些方法封装库.zip"主要包含了对Java插件API的详细整理和基于JDK的方法封装库,让我们一起来深入探讨。 首先,插件API(Plugin API)是软件系统中一种允许第三方...
10. **函数式编程**:Java 8引入了Lambda表达式和Stream API,为Java提供了函数式编程的支持,使代码更加简洁、高效。 以上只是Java工具类库中的一部分内容,实际上,它还包括许多其他实用的类,如`java.util....
【Java复习题与答案】 1. Java语言的注释: - 单行注释以`//`开始,用于简短的注释。...以上是根据提供的内容整理的Java相关知识点,涵盖了注释、类与继承、JVM特性、访问控制、程序结构、面向对象编程等多个方面。
4. **反射机制**:`java.lang.reflect`包提供了对运行时类信息的访问,包括类、接口、构造器、方法和字段。通过源码分析,可以了解反射如何动态地操作类和对象。 5. **并发编程**:`java.util.concurrent`包包含了...
System 类位于 java.lang 包中,是 Java 中最重要的类之一。 3. String, StringBuffer String 和 StringBuffer 是 Java 中两个重要的类,String 用于表示字符串,StringBuffer 用于表示可变字符串。StringBuffer ...
- **分类**:标准库(如 `java.lang`、`java.util` 等)、第三方库等。 - **用途**:提供丰富的功能,简化开发工作。 ### 五、输入输出 (IO) - **定义**:用于处理文件读写等操作。 - **分类**:字节流(如 `...
### Java的考试复习资料整理 #### 一、Java的基本概念及语法 - **Java平台的三个版本**: - **Java ME** (Micro Edition):主要用于嵌入式系统和移动设备。 - **Java SE** (Standard Edition):标准版,适用于...
这份"Java程序员常用英语单词800+"的资料,是根据Java API中五个核心包(lang, util, io, net, sql)的高频词汇整理得出的,涉及文档超过1700个。这些单词在计算机软件开发环境中具有特定含义,不仅包含通用词汇,还...
- **JTA (Java Transaction API)**: 用于管理事务处理,提供了与平台无关的事务处理机制。 #### 7. forward 与 redirect 的区别 - **forward**: - 在服务器端进行的页面重定向,不改变浏览器地址栏中的 URL。 - ...
根据提供的文件信息,我们可以整理出以下关键的Java知识点: ### 1. Java 类与接口的实现 - **`java.lang.Thread`**: 在Java中,如果一个类想要创建线程,可以通过继承`java.lang.Thread`类或者实现`Runnable`接口...
这份"Java十大基础笔记整理(PDF)"提供了全面的Java基础知识概览,适合初学者进行学习和复习。下面,我们将深入探讨Java的基础知识,涵盖核心概念、语法和编程实践。 1. **Java简介**:Java是由Sun Microsystems...
以上只是Java核心知识的冰山一角,实际的"JAVA核心知识点整理.pdf"可能会包含更多细节,如枚举、并发工具类、Lambda表达式、Stream API、模块系统(Jigsaw)、NIO.2、JPA、Spring框架等内容。深入学习并掌握这些知识...
* compact2:包含java.io、java.lang、java.util、java.text等API。 * compact3:包含所有的API。 使用javac命令可以根据profile编译应用程序,例如: $ javac -profile compact2 Test.java 如果不符合compact的...
在个人整理的Java学习资料中,我们可以看到以下几个关键知识点: 1. **JavaDoc注解**:JavaDoc是一种生成API文档的工具,常用的标记如`@author`用于指定程序作者,`@version`表示源文件的版本,`@deprecated`标记...