使用线程池有何注意事项呢?

  • java预定义的四种线程池
  1. SingleThreadExexcutor:单线程数的线程池
  2. FixedThreadPool:固定线程数的线程池
  3. CacheThreadPool:可缓存的线程池
  4. ScheduledThreadPoo:支持定时或周期任务的线程池
这四种线程池都有问题,建议自定义继承ThreadPoolExecutor,使用自定义的线程池
  • 四种线程池源码
上面四种线程池类都继承ThreadPoolExecutor,在创建时都是直接返回new ThreadPoolExecutor(参数),不同的是定义的ThreadPoolExecutor(参数)中参数不同,而ThreadPoolExecutor又继承ExecutorService类 (1)FixedThreadPool 使用线程池有何注意事项呢? (2)CacheThreadPool

 使用线程池有何注意事项呢?

(3)SingleThreadExecutor

使用线程池有何注意事项呢?

上面代码神似new FixedThreadPoop(1),但又有区别,因为外面多了一层FinalizableDelegatedExecutorService,其作用如下:

使用线程池有何注意事项呢?

可知,FixedThreadPoop可以向下转换,然后重新对其线程池进行配置参数【派变=(强转)基变,派变的范围大,向下转换即转为范围大的对象,简称“吓大”】,但SingleThreadExecutor不可以,故SingleThreadExecutor被创建后,无法再修改其线程池参数,真正地做到single单个线程。

(4)ScheduledThreadPool
public static ScheduledExecutorService new ScheduledThreadPool(int corePoolSize) 
{
   return new ScheduledThreadPoolExecutor(corePoolSize);
}
其中ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,故new ScheduledThreadPoolExecutor(corePoolSize)还是返回了父类构造new ThreadPoolExecutor();

  • 自定义线程池
  1. ThreadPoolExecutor构造方法

  使用线程池有何注意事项呢?

 其参数解释:

使用线程池有何注意事项呢?

  1. 自定义线程池
使用了有界队列,并自定义线程创建工厂ThreadFactory和拒绝策略handler

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException, IOException {
        int corePoolSize = 2;
        int maximumPoolSize = 4;
        long keepAliveTime = 10;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        ThreadFactory threadFactory = new NameTreadFactory();
        RejectedExecutionHandler handler = new MyIgnorePolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, threadFactory, handler);
        executor.prestartAllCoreThreads(); // 预启动所有核心线程        
        for (int i = 1; i <= 10; i++) {
            MyTask task = new MyTask(String.valueOf(i));
            executor.execute(task);
        }
        System.in.read(); //阻塞主线程
    }
    static class NameTreadFactory implements ThreadFactory {
        private final AtomicInteger mThreadNum = new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());
            System.out.println(t.getName() + " has been created");
            return t;
        }
    }

    public static class MyIgnorePolicy implements RejectedExecutionHandler {
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            doLog(r, e);
        }
        private void doLog(Runnable r, ThreadPoolExecutor e) {
            // 可做日志记录等
            System.err.println( r.toString() + " rejected");
//          System.out.println("completedTaskCount: " + e.getCompletedTaskCount());
        }
    }

    static class MyTask implements Runnable {
        private String name;
        public MyTask(String name) {
            this.name = name;
        }
        @Override
        public void run() {
            try {
                System.out.println(this.toString() + " is running!");
                Thread.sleep(3000); //让任务执行慢点
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public String getName() {
            return name;
        }
        @Override
        public String toString() {
            return "MyTask [name=" + name + "]";
        }
    }
}

运行结果:

  使用线程池有何注意事项呢?

其中7-10号线程被拒绝策略拒绝了,1、2号线程执行完后,3、6号线程进入核心线程池执行,此时4、5号线程在任务队列等待执行,3、6线程执行完再通知4、5线程执行

 

文章定期同步更新于公众号【小大白日志】,欢迎关注公众号:

使用线程池有何注意事项呢?

上一篇:Boot Repair-能一键修复ubuntu启动/引导项的软件(告别命令行)


下一篇:Python 线程池