zoukankan      html  css  js  c++  java
  • 线程池的三个使用方式

    Executor 读音[ɪɡˈzekjətə(r)]-一个贼可特
    Thread 读音[θred]-思略的
    1. Executors.newFixedThreadPool(5) 一池固定线程 适合长期任务,性能好,执行无序
    2. Executors.newSingleThreadExecutor() 一池一线程 一个任务一个任务执行,保证顺序性
    3. Executors.newCachedThreadPool() 一池多线程 适合短期异步任务或者负载很轻的服务,类似会扩容
    4. 仅了解-Executors.newScheduledThreadPool() 创建固定大小的线程,可以延迟或定时的执行任务。
    5. 仅了解-java8新出的Executors.newWorkStealingPool(int)

    Java中的线程池是通过Executor框架实现的,该框架用到了Executor,Executors[类似于Array与Arrays、Collection与Collections辅助工具类],ExecutorService,ThreadPoolExecutor[线程池底层用这个类]这几个类。

    体系结构:

    java.util.concurrent.Executor : 负责线程的使用与调度的根接口 
      |--ExecutorService 子接口: 线程池的主要接口 
        |--ThreadPoolExecutor 线程池的实现类 
        |--ScheduledExecutorService 子接口:负责线程的调度 
          |--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService *

    代码演示

    /**
     * 线程池三种试用方式
     * @Author小海
     * @Description:
     * @Date: Create in 22:28 2020-02-01
     */
    public class ExecutorsDemo {
        public static void main(String[] args) {
            // Executor
            // ThreadPoolExecutor;
            // 一个线程池创建5个固定线程,适合长期任务,性能好
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            // 一个线程池创建1个线程,一个任务一个任务执行,保证顺序性
            executorService = Executors.newSingleThreadExecutor();
            // 一个线程池创建N个线程,适合短期异步任务或者负载很轻的服务
            executorService = Executors.newCachedThreadPool();
            try {
                for (int i = 0; i < 10; i++) {
                    // 程序执行结果如下:最多只有5个线程同时执行任务
                    // execute只执行
                    executorService.execute(()->{
                        System.out.println(Thread.currentThread().getName() + "	 办理业务");
                    });
                    // submit带返回值
                    executorService.submit(new FutureTask<>(new Callable<Integer>() {
                        @Override
                        public Integer call() throws Exception {
                            return null;
                        }
                    }));
    
                    // 模拟长期任务,让线程执行时间变长
                    // Thread.sleep(200);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 关闭线程池
                executorService.shutdown();
            }
        }
    }
    
    
    

    newFixedThreadPool

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    

    适用场景:可用于Web服务瞬时削峰,但需注意长时间持续高峰情况造成的队列阻塞。

    newSingleThreadExecutor

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
    

    定眼一看,这里多了一层FinalizableDelegatedExecutorService包装。对比可以看出,FixedThreadPool可以向下转型为ThreadPoolExecutor,并对其线程池进行配置,而SingleThreadExecutor被包装后,无法成功向下转型。因此,SingleThreadExecutor被定以后,无法修改,做到了真正的Single。

    newCachedThreadPool

     public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    
    1. corePoolSize = 0,maximumPoolSize = Integer.MAX_VALUE,即线程数量几乎无限制;
    2. workQueue 为 SynchronousQueue 同步队列,这个队列类似于一个接力棒,入队出队必须同时传递,因为CachedThreadPool线程创建无限制,不会有队列等待,所以使用SynchronousQueue;
    3. 适用场景:快速处理大量耗时较短的任务,如Netty的NIO接受请求时,可使用CachedThreadPool。
  • 相关阅读:
    CDQZ Day5
    CDQZ Day4
    CDQZ Day3
    POJ 2226 Muddy Fields
    【其他】【生成图片】【1】通过phantomjs 进行页面截图
    【Redis】【1】一些报错处理
    【Java】【15】判断url对应的图片是否存在
    【HTML&CSS】【3】点击直接发送邮件
    【微信公众号开发】【16】遇到的问题
    【Oracle】【9】取前N条记录——rownum和row_number() over()的使用
  • 原文地址:https://www.cnblogs.com/xhyouyou/p/12465341.html
Copyright © 2011-2022 走看看