• ExecutorService接口线程池


    目录

    1、了解线程池

     2、线程池处理Runnable任务

    3、线程池处理Callable任务


    1、了解线程池

    什么是线程池?

    线程池就是一个可以复用线程的技术

    不使用线程池的问题 

    如果 用户每发起一个请求,后台就创建 一个 线程 来处理,下次新任务来了又要创建新线程, 而创建新线程的开销是很大的, 这样会严重影响系统的性能。
     

    谁代表线程池? 

    l JDK 5.0 起提供了代表线程池的接口: ExecutorService

    如何得到线程池对象

    方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象
    方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象

    ThreadPoolExecutor构造器的参数说明
    public ThreadPoolExecutor(int corePoolSize,
                                                int maximumPoolSize,
                                                long keepAliveTime,
                                                TimeUnit unit,
                                                BlockingQueue workQueue,
                                                ThreadFactory threadFactory,
                                                RejectedExecutionHandler handler)

    参数一:指定线程池的线程数量(核心线程): corePoolSize  --------------------不能小于0
    参数二:指定线程池可支持的最大线程数: maximumPoolSize  ------------------最大数量 >= 核心线程数量
    参数三:指定临时线程的最大存活时间: keepAliveTime --------------------------不能小于0
    参数四:指定存活时间的单位(秒、分、时、天): unit -----------------------------时间单位
    参数五:指定任务队列: workQueue ------------------------------------------不能为null
    参数六:指定用哪个线程工厂创建线程:threadFactory ----------------------------不能为null
    参数七:指定线程忙,任务满的时候,新任务来了怎么办: handler --------------------不能为null

    ThreadPoolExecutor创建线程池对象示例

    ExecutorService pools = new ThreadPoolExecutor(3, 5, 8 , TimeUnit.SECONDS,

    new ArrayBlockingQueue<>(6),Executors.defaultThreadFactory() ,

    new ThreadPoolExecutor.AbortPolicy());

    (此示例中常用线程有3个,一共可以同时执行5个线程(2个临时线程),当3个常用线程被占用,且任务队列中6个任务都占满了,则线程工厂会创建临时进程处理任务,当2个临时线程也被占用,再来任务的话就会被拒绝且抛出异常)

    线程池常见面试题

    临时线程什么时候创建啊?
        新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。

    什么时候会开始拒绝任务?
        核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝。

     2、线程池处理Runnable任务

    线程池如何处理Runnable任务
        使用ExecutorService的方法:
        void  execute(Runnable target)

    MyRunnable

    1. public class MyRunable implements Runnable{
    2. @Override
    3. public void run() {
    4. for (int i = 0; i < 5; i++) {
    5. System.out.println(Thread.currentThread().getName() + ":" + i);
    6. }
    7. System.out.println(Thread.currentThread().getName() + "进入休眠");
    8. try {
    9. Thread.sleep(1000000);
    10. } catch (InterruptedException e) {
    11. e.printStackTrace();
    12. }
    13. }
    14. }
    ThreadPool
    1. public static void main(String[] args) {
    2. //1、创建线程池对象
    3. ExecutorService pool = new ThreadPoolExecutor(3, 5, 6,
    4. TimeUnit.SECONDS, new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
    5. //2、任务给线程池处理
    6. Runnable target = new MyRunable();
    7. pool.execute(target);
    8. pool.execute(target);
    9. pool.execute(target);
    10. pool.execute(target);
    11. pool.execute(target);
    12. pool.execute(target);
    13. pool.execute(target);
    14. pool.execute(target);
    15. //创建临时线程
    16. pool.execute(target);
    17. pool.execute(target);
    18. //不创建,拒绝策略被触发
    19. pool.execute(target);
    20. //关闭线程池(开发中一般不会使用)
    21. //pool.shutdownNow();立即关闭,即使任务没有完成
    22. //pool.shutdown();会等待任务全部完成之后再关闭
    23. }

    3、线程池处理Callable任务

    线程池如何处理Callable任务,并得到任务执行完后返回的结果。
        使用ExecutorService的方法:
        Future submit(Callable command)

    MyCallable

    1. public class MyCallable implements Callable<String>{
    2. private int n;
    3. public MyCallable(int n) {
    4. this.n = n;
    5. }
    6. //重写call()方法(任务方法)
    7. @Override
    8. public String call() throws Exception {
    9. int sum = 0;
    10. for (int i = 1; i <= n; i++) {
    11. sum += i;
    12. }
    13. return Thread.currentThread().getName() + "执行1-" + n + "的结果是:" + sum;
    14. }
    15. }

    ThreadPool

    1. public static void main(String[] args) throws Exception {
    2. //1、创建线程池对象
    3. ExecutorService pool = new ThreadPoolExecutor(3, 5, 6,
    4. TimeUnit.SECONDS, new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
    5. //2、任务给线程池处理
    6. // Callable target = new MyCallable(100);
    7. // Future<String> f1 = pool.submit(target);
    8. Future<String> f1 = pool.submit(new MyCallable(100));
    9. Future<String> f2 = pool.submit(new MyCallable(200));
    10. Future<String> f3 = pool.submit(new MyCallable(300));
    11. Future<String> f4 = pool.submit(new MyCallable(400));
    12. // String s1 = f1.get();
    13. // System.out.println(s1);
    14. System.out.println(f1.get());
    15. System.out.println(f2.get());
    16. System.out.println(f3.get());
    17. System.out.println(f4.get());
    18. }
    19. }

  • 相关阅读:
    LeetCode 周赛 334,在算法的世界里反复横跳
    Python多线程(一)
    P1072 [NOIP2009 提高组] Hankson 的趣味题
    运维开发详解:从入门到精通
    前端设计模式之【外观模式】
    力扣刷题记录162.1-----127. 单词接龙
    【完整代码】2023数学建模国赛C题代码--蔬菜类商品的自动定价与补货决策
    小程序使用Canvas设置文字竖向排列
    AWS-GA(全球动态加速)-跨账号资源配置
    Spark SQL简介
  • 原文地址:https://blog.csdn.net/weixin_62023527/article/details/126520213