Java线程组与线程未捕获的异常

来源:互联网 发布:日本捕鲸 知乎 编辑:程序博客网 时间:2024/06/10 12:40
// 以编程的方式控制线程,在实际编程中,一般是在受控制的线程中定义一个标志变量,其他线程通过改变标志变量的值,来控制线程的暂停
// 恢复运行及自然终止,以下Test15类就是一个可以被控制的线程,状态包括 SUSP 暂停, STOP 终止,RUN 运行
// Test15类继承于ControlledThread类,因此Test15类是受控制的线程,在Test15类的run方法的while循环中,每次循环
// 结束前都会调用checkState()方法,判断接下来到底是继续运行,还是暂停或者终止运行
// 主线程通过调用Test15对象的setStat()方法来控制Test15线程,当实例变量的count值大于5时,就让Test15线程暂停,把Test15
// 对象的实例变量count设为0,然后再使Test15线程恢复运行,主线程最后终止Test15线程的运行


// ThreadGroup类表示线程组,他能够对一组线程进行集中管理,在创建一个线程对象时,可以通过构造方法指定它所属的线程组 Thread(ThreadGroup group, String name)
// 在构造线程组的实例时,也可以显示指定父亲线程组,例如:ThreadGroup(ThreadGroup group, String name)
// ThreadGroup类的activeCount()方法返回当前活着的线程,enumerate(Thread[] tarray) 方法把当前活着的线程的引用拷贝到参数tarray中
// 问题,假如在执行group.activeCount()方法时有5个活着的线程,那么activeCount的值为5,但是当执行group.enumerate(machines)方法时已经有6个活着的线程,那么enumerate()
// 方法只会向machines数组中存放5个线程的引用,还有一个线程被忽略,所以不推荐使用ThreadGroup类,这个类还有一个有用的功能是uncaughtException()方法


// 处理线程未捕获的异常:如果当前线程没有捕获异常,那么java虚拟机会寻找相关的UncaughtExceptionHandler实例,如果找到,就调用他的uncaughtException(Thread t, Throwable e)方法
// 在Thread类中提供了一个公共的静态的UncaughtExceptionHandler内部接口,他负责处理线程未捕获的异常,接口完整名是Thread.UncaughtExceptionHandler,他的唯一方法是
// uncaughtException(Thread t,Throwable e)参数t表示抛出异常的线程,参数e表示具体的异常
// Thread类中提供了两个设置异常处理类的方法
// setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
// setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
// 第一个方法是静态方法,设置线程类的默认异常处理器,第二个方法是实例方法,设置线程实例的当前异常处理器
// ThreadGroup实现了Thread.UncaughtExceptionHandler接口,当一个线程实例抛出未捕获的异常时,java首先查找线程实例的当前异常处理器,没有找到,就会找实例所属的线程组作为异常处理器,都是调用
// uncaughtException()方法,还是没有则调用当前线程类的默认异常处理器,最后,就把来自方法调用堆栈的异常信息打印到标准输出流System.err中


// ThreadLocal类:这个类用来存放线程的局部变量,每个线程都有单独的局部变量,彼此之间不会共享,ThreadLocal<T>类主要包括以下三个方法:

class ControlledThread extends Thread{public static final int SUSP = 1;public static final int STOP = 2;public static final int RUN = 0;private int state = RUN;public synchronized void setStat(int state){this.state = state;if(state == RUN){notify();}}public synchronized boolean checkStat() {while (state == SUSP) {try {System.out.println(Thread.currentThread().getName() + ":wait");wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (state == STOP) {return false;}return true;}}public class Test15 extends ControlledThread{private int count;public void run(){// 循环判断Test15的checkStat()是否进入终止状态,返回true就一直运行下去while(true){synchronized (this) {count++;System.out.println(Thread.currentThread().getName()+":run " + count+ " times");}if(!checkStat()){System.out.println(Thread.currentThread().getName()+":stop");break;}}}public synchronized int getCount(){return count;}public synchronized void reset(){count=0;System.out.println(Thread.currentThread().getName()+":reset");}public static void main(String[] args) {Test15 test15 = new Test15();// 启动test15线程test15.start();// for 循环200次for(int i = 0;i<200;i++){// 由于test15线程运行了一段时间后,将CPU使用权让给主线程,主线程判断count的值是否大于5,大于5就进入暂停状态,此时test15获得了CPU使用权,state == SUSP此时进入等待状态// 主线程运行reset方法将count值重新设置为0,将ControlledThread.RUN设置为运行状态,主线程中的for循环次数等于200时,则设置test15线程为停止状态if(test15.getCount()>5){test15.setStat(ControlledThread.SUSP);yield();test15.reset();test15.setStat(ControlledThread.RUN);}yield();}test15.setStat(ControlledThread.STOP);}}// (自定义)异常处理class MichineHandler implements Thread.UncaughtExceptionHandler{@Overridepublic void uncaughtException(Thread t, Throwable e) {}}// 线程组默认实现了Thread.UncaughtExceptionHandler,所以可以设置线程组的异常处理class MichineGroup extends ThreadGroup{public MichineGroup() {super("MichineGroup");}@Overridepublic void uncaughtException(Thread t, Throwable e) {// TODO Auto-generated method stubsuper.uncaughtException(t, e);}}


0 0
原创粉丝点击