十五.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将不能再次被使用.
相关推荐
标签:activation、sun、jakarta、jar包、java、中英对照文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
springboot 打war部署到apache-tomcat-7.0.69中启动报错:java.lang.NoClassDefFoundError: javax/el/ELManager 下载javax.el-api-3.0.0.jar,放到 tomcat/lib包下可以解决,原来的el-api.jar版本较低
通过错误描述我们发现java.lang.NoClassDefFoundError: javax/mail/MessagingException,主要说找不到这个类。通过查询发现是缺少javax.mail-api-1.6.2.jar和activation-1.1.1.jar包。在maven上下载即可
com.springsource.tcl.lang.jacl-1.4.1生成报错替换包.zip
jdk升级之后出现异常:java.lang.NoClassDefFoundError: javax/xml/ws/Service 1、解决方案jdk降级至1.8之前 2、由于JDK9以后,去除了javax.xml包需要引入对应的jar包 <groupId>javax.activation <artifactId>...
org.eclipse.swt.SWTError: No more handles [MOZILLA_FIVE_HOME=''] (java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: no swt-mozilla-gtk-4335 in java.library.path no swt-mozilla-gtk ...
EWS java API 里面包含 Java调用EWS 接口所需要的所有jar包如: commons-logging-1.2.jar joda-time-2.8.jar commons-lang3-3.4.jar httpclient-4.4.1.jar httpcore-4.4.1.jar
java.lang.IllegalStateException: Failed to read Class-Path attribute from manifest of jar file:/XXX 出现这个问题的解决方案就是将原有的jar删除 然后重新下载过一遍就可以使用
idea启动项目报错 java.lang.NegativeArraySizeException解决方法
标签:scala、lang、modules、java8、compat、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明...
Tomcat启动报错 java.lang.ClassNotFoundException: org.apache.jsp.index_jsp,检查你的项目中是否存在jsp-api.jar,jstl-api.jar,servlet-api.jar。
commons-lang3.3.1.jar、Apache Commons包中的一个,包含了一些数据类型工具类,是java.lang.*的扩展。必须使用的jar包。为JRE5.0+的更好的版本所提供 Jar文件包含的类: META-INF/MANIFEST.MFMETA-INF/LICENSE....
jar包,官方版本,自测可用
标签:apache、commons、lang3、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...
java.lang.NoSuchFieldError: Companion 问题的解决方案
vscjava.vscode-java-dependency-0.5.1 deerawan.vscode-hasher-1.0.1 vscjava.vscode-java-debug-0.20.0 scala-lang.scala-0.3.4 eg2.vscode-npm-script-0.3.8 vscjava.vscode-maven-0.18.1 ms-vscode.go-0.11.4 ...
报错 java.lang.OutOfMemoryError: PermGen space 报错 java.lang.OutOfMemoryError: Java heap 启动报错java.lang.ClassNotFoundException: 1catalina.org.apache.juli.FileHandler JAVA_OPTS="-server -Xms800m ...
标签:scala、lang、reflect、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心...
标签:apache、lang3、commons、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...
export NLS_LANG='simplified chinese_china'.ZHS16GBK export LD_LIBRARY_PATH=$ORACLE_HOME/lib export PATH=$ORACLE_HOME/bin:$PATH 1.6 使配置完的环境变量生效 #source ~/.bashrc 1.7 连接数据库测试 #...