线程优先级
Java中,每一个线程都有一个线程优先级。默认情况下,一个线程继承它的父线程的优先级。
设置优先级,使用Thread的setPriority方法
优先级的范围为Thread.MIN_PRIORITY 到 Thread.MAX_PRIORITY
这两个代表1到10,setPriority的参数必须在1到10之间,否则会抛异常,Thread.NORM_PRIORITY为5
当线程调度器有机会选择新的线程时,首先会选择具有较高优先级的线程,但是,线程优先级是高度依赖系统的,当虚拟机依赖于宿主机平台的线程实现机制时,Java线程的优先级被映射到宿主机平台的优先级上,优先级个数也许会更多,也许会更少
比如,Windows有7个优先级。一些Java优先级将映射到相同的操作系统优先级。在Oracle为Linux提供的虚拟机中,线程的优先级被忽略,所有的线程具有相同的优先级
看下面的程序实例
class MyRunnable implements Runnable{
private int ticket =600;
private Object obj = new Object();
public void run() {
while(true){
synchronized (this){
if(ticket>0){
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"sale "+ticket--);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
设置优先级,我讲线程th4的优先级设置为6,在5个线程中最高
public class ThreadDemo{
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
Thread th1 = new Thread(runnable);
Thread th2 = new Thread(runnable);
Thread th3 = new Thread(runnable);
Thread th4 = new Thread(runnable);
Thread th5 = new Thread(runnable);
th1.setPriority(1);
th1.setName("one");
th2.setPriority(1);
th2.setName("two");
th3.setPriority(1);
th3.setName("three");
th4.setPriority(6);
th4.setName("four");
th5.setName("five");
th5.setPriority(2);
th1.start();
th2.start();
th3.start();
th4.start();
th5.start();
}
}
输出结果,可以看到,在线程one抢到执行权开始打印出1次,然后退出了同步代码块,释放了锁,此时其他等待的线程开始竞争锁,抢了几次或,线程4抢的最多,因为4的优先级最高,CPU会优先调度线程4
守护线程
通过Thread的方法setDaemon设置,当参数为true时,设置为该线程为守护线程
设置为守护线程的线程即是用户线程又是守护线程。守护线程的唯一用途是为其他线程提供服务。
当线程只剩下守护线程时,JVM虚拟机就会退出了。不要用守护线程做一些操作资源的事情,比如关机之类的,因为守护线程有可能会因为异常而中断
- thread.setDaemon必须在start()之前设置
- 在守护线程中创建的线程也是守护线程
- 守护线程不应该去访问固有资源
未捕获的异常处理器
线程的run方法不能抛出任何受检异常,但是非受检异常会导致线程终止。在这种情况下,线程就死亡了。
但是,不需要任何catch子句来处理可以被传播的异常。想反,就在线程死亡之前,异常被传递到一个用于
未捕获异常的处理器
该处理器必须属于一个实现Thread.UncaughtExceptionHandler接口的类。这个接口只有一个方法
void uncaughtException(Thread t,Throwable e)
可以用setUncaughtExceptionHandler方法为任何线程设置一个处理器。也可以用Thread.setDefaultUncaughtExceptionHandler为所有线程安装一个默认的处理器。替换处理器可以使用日志API发送未捕获异常的报告到日志文件
如果不安装默认的处理器,默认的处理器为空。但是如果不为独立的线程安装处理器,此时的处理器就是该线程的ThreadGroup对象
关于UncaughtException的更多学习,请看我的另外一篇文章
http://blog.csdn.net/daiyutage/article/details/70142686