线程池的理解和实践【3】

本文介绍了如何在Java中自定义线程池,包括使用线程工厂设定线程名称、优先级和守护状态。此外,还展示了通过扩展ThreadPoolExecutor来监控任务执行和处理异常的方法,如使用beforeExecute方法记录任务信息,以及通过Future对象捕获异常。
摘要由CSDN通过智能技术生成

前两篇中我们介绍了什么是线程池 ,线程池的主要参数,快速手写一个简单的线程池,这一篇中我们介绍一些,线程池的重要拓展。

自定义线程创建

在之前例子里面 我创建线程池 参数只有四个,还有两个是线程工厂和拒绝策略。

这里的线程工厂作为参数的意义就是可以让我们自定义线程的创建:

比如 自定义线程的名称。 自定义线程的优先级。 改变线程是否为守护线程等等

我们就在上一篇的基础上改

    public CustomThreadPool(){
       executorService = new ThreadPoolExecutor(
               5,
               6,
               30,
               TimeUnit.SECONDS,
               new ArrayBlockingQueue<>(3),
               new ThreadFactory() {
                   @Override
                   public Thread newThread(Runnable r) {
                       Thread thread = new Thread();
                       thread.setName("定制化名称");
                       thread.setDaemon(true);
                       thread.setPriority(3);//优先级
                       return thread;
                   }
               });
    }

拓展线程池

当我们想要更详细的监控每个线程执行的时间 开始和结束
ThreadPoolExecutor 提供了三个方法:可以做到有头有尾

public class MyThreadPoolExecutor extends ThreadPoolExecutor {
    // 继承 ThreadPoolExecutor 类并重写 beforeExecute 方法
    protected void beforeExecute(Thread t, Runnable r) {
        // 在任务执行之前,记录任务信息和线程信息
        System.out.println("Task is about to execute: " + r.toString());
        System.out.println("Thread name: " + t.getName());
    }

    // 构造方法和其他自定义逻辑...
}

// 在使用时创建自定义的线程池
ExecutorService executor = new MyThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

// 提交任务给线程池
executor.submit(new MyTask());

正确的处理任务异常

在每一个线程池的run()执行方法中,万一有个什么三长两短,跑挂了。它是不会抛出异常的,程序也不会停止。 这对我们排查信息很重要。

这里推荐两个方法:
1.在run内手动捕获 并打印堆栈。

public class PrintTimeTask implements Runnable{
    @Override
    public void run() {
        try {
            System.out.println("当前线程:"+Thread.currentThread().getName()+"-打印时间:"+System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
            //log.error()
        }
    }
}

2.使用future对象。使用submit提交task

它会返回一个future的结果对象。 这里面会记录线程的运行情况 及错误日志

          // customThreadPool.execute(timeTask);
            Future future = customThreadPool.submit(timeTask);
            future.get();

这三种线程池的拓展希望新手自己多敲几遍熟练掌握

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值