java多线程编程核心技术(第七章)-读书笔记

java多线程编程核心技术

第七章、拾遗增补

7.1 线程的状态

线程对象在不同的运行时期有不同的状态,状态信息就存在于Thread.State枚举类中。

可以使用Thread.currentThread().getState()方法获取线程状态。

在这里插入图片描述

7.2 线程组

可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程。这样的组织结构有些类似于树的形式。线程组的作用是,可以批量的管理线程或线程组对象,有效地对线程组或线程组对象进行组织。

在这里插入图片描述

7.2.3 线程组自动归属特性

在实例化一个ThreadGroup线程组x时,如果不指定所属的线程组,则x线程组自动归到当前线程对象所属的线程组中,成为它的子线程组。

7.2.6 组内的线程批量停止

当调用线程组ThreadGroup的interrupt()方法时,可以将该组中的所有正在运行的线程批量停止(当然只是做了标记,并不会真的停止)。

7.2.7 递归与非递归取得线程组

示例代码:

    ThreadGroup[] listGroup = new ThreadGroup[Thread.currentThread().getThreadGroup().activeCount()];
    // 传入true是递归取得子组及子孙组,传入false则只取得子组
    boolean recurse = true;
    Thread.currentThread().getThreadGroup().enumerate(listGroup, recurse);

7.5 线程中出现异常的处理

方法setUncaughtExceptionHandler()是给指定线程对象设置异常处理器。在Thread类中还可以使用setDefaultUncaughtExceptionHandler()方法对所有线程对象设置异常处理器。

示例代码:

/**
 * 线程对象异常处理
 */
public class Test48ThreadException {
    public static void main(String[] args) {
        // 使用setDefaultUncaughtExceptionHandler来设置线程类的默认的异常处理器
        MyThread48.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("线程:" + t.getName() + "出现了异常,被类级别的UncaughtExceptionHandler处理。");
//                e.printStackTrace();
            }
        });

        MyThread48 myThread4801 = new MyThread48();
        // 使用setUncaughtExceptionHandler方法来设置某个具体线程对象的异常处理器。
        myThread4801.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("线程:" + t.getName() + "出现了异常,被对象级别的UncaughtExceptionHandler处理。");
//                e.printStackTrace();
            }
        });

        MyThread48 myThread4802 = new MyThread48();

        myThread4801.setName("myThread4801");
        myThread4802.setName("myThread4802");

        myThread4801.start();
        myThread4802.start();

        /*
        从运行结果可以看出,
        myThread4801的异常由线程对象调用setUncaughtExceptionHandler方法设置的UncaughtExceptionHandler处理了,
        myThread4802的异常由MyThread48类调用的setDefaultUncaughtExceptionHandler方法设置的UncaughtExceptionHandler处理了。

        运行结果:
        线程:myThread4801出现了异常,被对象级别的UncaughtExceptionHandler处理。
        线程:myThread4802出现了异常,被类级别的UncaughtExceptionHandler处理。
        */
    }
}
class MyThread48 extends Thread {
    @Override
    public void run() {
        String username = null;
        // 这一句一定会抛空指针异常
        System.out.println(username.hashCode());
    }
}

7.6 线程组内处理异常

我们可以通过继承ThreadGroup类,并重写uncaughtException方法来对某个线程组进行整体的异常处理,例如某个线程出错则停止组内所有线程。

示例代码:

/**
 * 线程组对象异常处理
 */
public class Test49ThreadGroupException {
    public static void main(String[] args) {
        // 使用我们自己实现的ThreadGroup49,其中指定了当某线程出错时,将组内所有线程interrupt的操作
        ThreadGroup49 group = new ThreadGroup49("my group");

        // 创建几个会一直运行的线程
        MyThread49[] myThread49 = new MyThread49[5];
        for (int i = 0; i < myThread49.length; i++) {
            myThread49[i] = new MyThread49(group, "线程" + i, "1");
            myThread49[i].start();
        }

        // 创建一个会在运行后报错的线程
        MyThread49 newT = new MyThread49(group, "报错线程", "a");
        newT.start();

        /*
        从结果可以看出,在抛出异常后,所有线程都收到了interrupt的消息,并由代码控制退出了循环
        运行结果:
        死循环中:线程4
        java.lang.NumberFormatException: For input string: "a"
        死循环中:线程3
        死循环中:线程3
            at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        死循环中:线程1
            at java.lang.Integer.parseInt(Integer.java:580)
        死循环中:线程3
            at java.lang.Integer.parseInt(Integer.java:615)
        死循环中:线程3
            at org.llbqhh.study.java.book.java_multi_thread_programming.MyThread49.run(Test49ThreadGroupException.java:44)
        死循环中:线程4
        死循环中:线程0
        死循环中:线程2
        死循环中:线程3
        死循环中:线程1
         */
    }
}
class ThreadGroup49 extends ThreadGroup {
    public ThreadGroup49(String name) {
        super(name);
    }

    /**
     * 重写uncaughtException方法,对整组线程进行interrupt操作
     * @param t
     * @param e
     */
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        super.uncaughtException(t, e);
        // 停止整组对线程
        this.interrupt();
    }
}
class MyThread49 extends Thread {
    private String num;
    public MyThread49(ThreadGroup group, String name, String num) {
        super(group, name);
        this.num = num;
    }

    @Override
    public void run() {
        int numInt = Integer.parseInt(num);
        while (!this.isInterrupted()) {
            System.out.println("死循环中:" + Thread.currentThread().getName());
        }
    }
}

最后

1、所有代码示例都在github中
https://github.com/llbqhh/LlbStudy/tree/master/StudyJava/src/main/java/org/llbqhh/study/java/book/java_multi_thread_programming
2、感谢您的阅读,如果对内容感兴趣可以关注我的公众号,搜索【猫耳山自习室】或扫描下方二维码,会有定期更新

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值