线程可以有如下六种状态:
- New 新生
- Runnable 可运行
- Blocked 被阻塞
- Waiting 等待
- Timed waiting 计时等待
- Terminated 被终止
new,顾名思义,指当使用new操作符创建线程时线程所处的状态。
当调用start方法时,线程处于runnable状态。
线程的具体调度由操作系统完成,操作系统会考虑线程的优先级来完成调度。
抢占式调度,即操作系统给每一个可运行线程一个时间片来执行任务,时间片用完时,操作系统剥夺该线程的运行权,并给予其他线程机会。
协作式调度,即一个线程只有在调用yield方法,或者被阻塞或等待时,线程才失去失去控制权,一般仅用在手机等小型设备。
当一个线程试图获取其他线程持有的对象锁,该线程进入blocked阻塞状态,当本线程获取到该锁之后,阻塞解除。
当线程等待另一个线程通知调度期一个条件时,进入waiting等待状态。
有几个方法有一个超时参数,调用他们导致线程进入计时等待timed waiting状态,例如sleep。
terminated则有如下两个原因:1.因run方法正常退出而自然死亡 2.因为一个没有捕获的异常终止了run方法而意外死亡。
线程优先级:
使用setPriority设置优先级在MIN_PRIORITY(1)到MAX_PRIORITY(10)之间。
线程优先级高度依赖于系统,java的线程优先级会被映射到宿主机平台的优先级上。
守护线程:
使用 t.setDaemon(true); 将线程转换为守护线程,守护线程用来为其他线程提供服务,例如计时线程。
当只剩下守护线程时,虚拟机退出。
守护线程不应该访问固有资源,如文件,数据库,因为它会在任何时候发生中断。
未捕获异常处理器:
线程的run方法不能抛出任何被检测的异常,但是,不被检测的异常会导致线程终止。
但是,也不需要catch来捕获异常,相反,在线程终止之前,异常被传递到一个用于未捕获异常的处理器。
该处理器必须属于一个实现Thread 。UncaughtExceptionHandler接口的类,这个接口只有一个方法:
void uncaughtException(Thread t,Throwable e)
使用setUncaughtExceptionHandler为任何线程安装一个处理器,Thread类也提供为所有线程安装一个默认的处理器的方法setDefaultUncaughtExceptionHandler.
如果不安装默认的处理器,默认的处理器为空。但是,如果不为独立的线程安装处理器,此时的处理器就是该线程的ThreadGroup对象。
线程组(ThreadGroup):
线程组是一个可以同一管理的线程集合,默认情况下,创建的所有线程属于相同的线程足。(有更好的对于线程集合的操作,所以不要在自己的程序中使用线程组)。
线程组实现Thread.UncaughtExceptionHandler接口。
如果该线程组有父线程组,则调用父线程组的方法。否则,如果Thread.getDefaultUncaughtExceptionHandler返回一个非空的处理器,则调用该处理器。否则,如果Throwable是ThreadDeath的一个实例,什么都不做。否则,线程的名字以及Throwable的栈总计被输出到System.err上。