Java 并发编程学习笔记(14) ----ThreadPoolExecutor 线程池的方法

1.1 shutdown() 和 shutdownNow()

方法shutdown()的作用是使当前未执行完的线程继续执行,而不再添加新的任务,
shutdown()方法是不阻塞的。
方法shutdownNow()的作用是中断所有的任务,并且抛出InterruptdException
异常(需要和任务中的if(Thread.currentThread().isInterrupted() == true) 结合使用)。
未执行的线程不再执行,也从执行队列中清除。

2.1 工厂ThreadFactory + UncaughtExceptionHandler 处理异常

可以通过重写ThreadFactory 中的newThread(Runnable r)方法来对线程的一些属性进行定制化。

2.2 代码


package com.lhc.concurrent.executor.factory;

import java.util.Date;
import java.util.concurrent.ThreadFactory;

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

2.3 测试类


package com.lhc.concurrent.executor.factory;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
        //抛出异常
        String str = null;
        System.out.println(str.contains(""));
        System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
    }

    public static void main(String[] srgs){
        MyRunnable myRunnable = new MyRunnable();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 8, 20, TimeUnit.SECONDS,
                new LinkedBlockingDeque<Runnable>());
        executor.setThreadFactory(new MyTHreadFactory());
        executor.execute(myRunnable);
    }
}

2.4运行结果

name:Mon May 13 17:16:57 GMT+08:00 2019 1557739017491
java.lang.NullPointerException
自定义处理异常
name:Mon May 13 17:16:57 GMT+08:00 2019:null
at com.lhc.concurrent.executor.factory.MyRunnable.run(MyRunnable.java:13)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at
java.lang.Thread.run(Thread.java:745)

3.1 方法afterExecute() 和 beforeExecute()

在线程池ThreadPoolExecutor 类中重写这两个方法可以对线程池中执行的线程对象实现监控。

3.2 代码


package com.lhc.concurrent.executor.before;

public class MyThread extends Thread{
    public MyThread(String name) {
        super();
        this.setName(name);
    }

    @Override
    public void run() {
        System.out.println("打印了! begin" + this.getName() + " " + System.currentTimeMillis());
        try {
            Thread.sleep(4000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("打印了! end" + this.getName() + " " + System.currentTimeMillis());
    }
}

3.3 测试类


package com.lhc.concurrent.executor.before;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyThreadPool extends ThreadPoolExecutor{
    public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                        BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        System.out.println(((MyThread)r).getName() + "准备执行");
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        System.out.println(((MyThread)r).getName() + "执行完毕");
    }

    public static void main(String[] args){
        MyThreadPool myThreadPool = new MyThreadPool(2, 2, Integer.MAX_VALUE,
                TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
        myThreadPool.execute(new MyThread("0001"));
        myThreadPool.execute(new MyThread("0002"));
        myThreadPool.execute(new MyThread("0003"));
        myThreadPool.execute(new MyThread("0004"));
    }
}


4.1 方法execute() 与submit的区别

1) 方法execute() 没有返回值,而submit()方法可以有返回值
2) 方法execute() 在默认的情况下异常直接抛出,不能捕获,但可以通过自定义ThreadFactory 的方式进行捕获,而submit()方法在默认的情况下,可以
捕获异常。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值