不从头开始写了。
线程状态
- New(新生):当使用new操作符创建一个新的线程时,该线程还没有运行(没有调用
start
方法),这就意味着它的状态是new。 - Runnable(可运行):一旦调用
start
方法,线程就处于可运行状态,一个可运行的线程可能正在运行也可能没有运行,这取决系统给线程提供的运行时间。一旦一个线程开始运行,它不必始终保持运行。 - Blocked(被阻塞)
- Waiting(等待)
- Timed waiting(计时等待)
:被阻塞线程和等待线程,它暂时不活动,不运行任何代码且消耗最少的资源。直到线程调度器重新激活它。 - Terminated(被终止):线程因如下两个原因之一而被终止:
- 因为
run
方法正常退出而自然死亡 - 因为一个没有捕获的异常终止了
run
方法而意外死亡
特别是,可以调用线程的stop
方法杀死一个线程。该方法抛出一个ThreadDeath
错误对象,由此杀死线程。但是stop
方法已过时,不要在自己的代码中调用它。
- 因为
中断线程
当线程的
run
方法执行方法体中的最后一条语句,并经由return
语句返回时,或者出现了在方法中没有捕获的异常时,线程将终止。
有一种可以强制线程终止的方法:interrupt
:当对一个线程调用interrupt
方法时,线程的中断状态
将被置位。这是每个线程都具有的一个boolean
标志位,每个线程都应该不时的检查它,以判断线程是否被中断。方法如下:
先获取到当前线程,然后调用isInterrupt
方法while(!Thread.currentThread.isInterript() && *maor work to do*) { do more work }
但是,如果线程被阻塞, ,就无法检测中断状态,这是产生InterruptedException异常的地方,当在一个被阻塞的线程(wait或者sleep)上调用interrupt方法时,阻塞调用将会被InterruptedException异常中断。一个被中断的线程并不一定要终止,中断一个线程不过是引起它的注意,被中断的线程可以决定如何响应中断,这种线程的run方法具有如下形式
public void run()
{
try
{
while( !Thread.currentThread().isInterrupted() && morework)
{
do more work
}
}
catch(InterruptedException e){
//thread was interrupted during sllep or wait
}
finally{
cleanup,if required
}
}
如果在中断状态被置位的情况下调用sleep,它不会休眠,相反,它将清除这已状态并抛出InterruptedException异常。值得注意的是,线程里面有几个个非常相似的方法
+ boolean interrupted()
//静态方法,检测线程是否被中断,调用该方法会清除该线程的中断状态
+ void interrupt()
//中断当前线程
+ boolean isInterrupted()
//实例方法,检测当前献策和嗯是否被中断,不会改变线程的中断状态
线程的属性
- 线程优先级
在Java中,每一个线程有一个优先级。默认情况下,一个线程继承它的父线程的优先级,可以用setPriority
方法提高或降低任何一个线程的优先级。可以将优先级设置为MIN_PRIORITY(在Thread类中被定义为1)
与MAX_PRIORITY(在Thread类中被定义为10)
之间的任何值。
每当线程调度器有机会选择新线程时,它首先选择具有较高优先级的线程。但是线程优先级是高度依赖系统的。当Java的优先级被映射到到宿主机平台的优先级上,优先级的个数也许更多,也许更少。 - 守护线程
可以通过调用t.SetDaemon(true)
将线程转化为守护线程。守护线程唯一的用途就是为其他线程提供服务,当只剩下守护线程时,虚拟机就退出了,因为只剩下守护线程,就没有必要继续运行程序了。守护线程应该永远不要去访问固有资源,如文件、数据库等,因为它会在任何时候甚至是一个操作的中间发生中断。
未捕获异常处理器
- 线程的run方法不能抛出任何被检测的异常,但是不被检测的异常会导致线程终止,在这种情况下,线程就死亡了。但是不需要任何catch字句来处理可以被传播的异常,相反,在线程死亡之前异常被传递到一个用于处理未捕获异常的处理器。该处理器必须属于一个实现
Thread.UncaughtExceptionHandler
接口的类,这个接口只有一个方法:public void uncaughtException(Thread t, Throwable e)
。如果不安装默认的处理器,默认的处理器为空,但是,如果不为独立的线程安装处理器,此时的处理器就是该线程的ThreadGroup对象。
ThreadGroup类实现Thread.UncaughtExceptionHandler
接口,它的uncaughtException
做了如下操作:
1) 如果该线程组有父线程组,那么父线程组的uncaughtException
方法就会被调用
2) 否则,如果Thread.getDefaultUncaughtExceptionHandler()
返回一个非空处理器,则调用该处理器。
3) 否则,如果Throwable
是ThreadDeath
的一个实例,什么都不做。
4) 否则,线程的名字以及Throwable
的栈踪迹被输出到System.err上。