【并发编程】- 线程池使用自定义线程工厂、自定义处理异常

368 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情

工厂ThreadFactory+execute()+UncaughtExceptionHandler处理异常

线程池中创建的线程属性进行定制化,需要配置ThreadFactory线程工厂

线程执行代码如下:

public class FirstRunnable implements Runnable {

    @Override
    public void run() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        try {
            System.out.println(Thread.currentThread().getName() +"  开始时间:"+simpleDateFormat.format(new Date()));
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() +"  结束时间:"+simpleDateFormat.format(new Date()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

线程工厂代码如下:

public class TheThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("Eleven");
        return thread;
    }
}

运行类代码如下:

public class CustomThreadFactoryRun {
    public static void main(String[] args) {
        FirstRunnable firstRunnable = new FirstRunnable();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 6, 999, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new TheThreadFactory());
        threadPoolExecutor.execute(firstRunnable);
    }
}

运行结果如下:

Eleven  开始时间:14:13:09
Eleven  结束时间:14:13:10

使用了构造方法传递自定义ThreadFactory.

修改运行类代码,使用setThreadFactory()方法设置自定义ThreadFactory

public class CustomThreadFactoryRun {
    public static void main(String[] args) {
        FirstRunnable firstRunnable = new FirstRunnable();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 6, 999, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        threadPoolExecutor.setThreadFactory(new TheThreadFactory());
        threadPoolExecutor.execute(firstRunnable);
    }
}

修改线程执行代码如下:

public class FirstRunnable implements Runnable {


    @Override
    public void run() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        try {
            System.out.println(Thread.currentThread().getName() +"  开始时间:"+simpleDateFormat.format(new Date()));
            Thread.sleep(1000);
            String result = "";
            result.indexOf(0);
            System.out.println(Thread.currentThread().getName() +"  结束时间:"+simpleDateFormat.format(new Date()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下:

Eleven  开始时间:14:47:15
Exception in thread "Eleven" java.lang.NullPointerException
	at com.ozx.concurrentprogram.executor.service.FirstRunnable.run(FirstRunnable.java:21)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

当线程运行异常时,则JDK抛出异常,无法自行处理处理异常。

线程工厂代码如下:

public class CustomThreadFactory implements ThreadFactory {

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("Gxin :"+ new Date());
        thread.setUncaughtExceptionHandler(
                new Thread.UncaughtExceptionHandler(){
                    @Override
                    public void uncaughtException(Thread t, Throwable e) {
                        System.out.println("自定义处理异常:"+t.getName()+" "+e.getMessage());
                        e.printStackTrace();
                    }
                }
        );
        return thread;
    }
}

运行类代码如下:

public class CustomThreadFactoryRun {
    public static void main(String[] args) {
        FirstRunnable firstRunnable = new FirstRunnable();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 6, 999, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        threadPoolExecutor.setThreadFactory(new CustomThreadFactory());
        threadPoolExecutor.execute(firstRunnable);
    }
}

运行结果如下:

Gxin :Wed Jun 15 15:12:13 CST 2022  开始时间:15:12:13
自定义处理异常:Gxin :Wed Jun 15 15:12:13 CST 2022 null
java.lang.NullPointerException
	at com.ozx.concurrentprogram.executor.service.FirstRunnable.run(FirstRunnable.java:21)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

从运行结果看出使用自定义线程工厂时,线程如果出现异常完全可以自定义处理。