zoukankan      html  css  js  c++  java
  • JAVA基础知识|Executors提供的四种线程池

    一、Thread与Executors

     开启新的线程,我们经常会采用如下方法:

            Thread thread =new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("new thread");
                }
            });

    通过new Thread()的方式,会导致很多弊端,如下:

    • 每一次都通过new Thread的方式,性能差。
    • 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致宕机。
    • 缺乏定时执行、定期执行、线程中断等功能。

    Executors提供的四种线程池有效的解决以上问题

    二、Executors提供的四种线程池

    • newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    • newScheduledThreadPool 创建一个定长线程池,同时支持定时及周期性任务执行。
    • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。

    三、newCachedThreadPool

            ExecutorService executorService1 = Executors.newCachedThreadPool();
            Future<String> future = executorService1.submit(new Callable<String>() {
    
                @Override
                public String call() throws Exception {
                    return "newCachedThreadPool";
                }
            });
            try {
                System.out.println(future.get());
            } catch (Exception e) {
                e.printStackTrace();
            }

    四、newFixedThreadPool

            ExecutorService executorService2 = Executors.newFixedThreadPool(3);//定长3个线程
            for (int i = 0; i < 10; i++) {
                executorService2.execute(new Runnable() {//execute与submit的区别
                    @Override
                    public void run() {
                        try {
                            System.out.println("定长三个线程");
                            TimeUnit.SECONDS.sleep(3);//注意和Thread.sleep(3000)的区别
                        } catch (InterruptedException e) {
                            System.out.println("InterruptedException");
                        } catch (Exception e) {
                            System.out.println("Exception");
                        }
                    }
                });
            }

    每隔三秒钟,打印三条数据

    五、newScheduledThreadPool

            ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);//定长三个线程
            scheduledThreadPool.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("延迟三秒输出");
                }
            }, 3, TimeUnit.SECONDS);

    延迟三秒输出

            ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);//定长三个线程
            scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    System.out.println("延迟1秒,然后定期每三秒执行一次");
                }
            },1, 3, TimeUnit.SECONDS);

    延迟一秒,然后定期执行

    六、newSingleThreadExecutor

            ExecutorService executorService4 = Executors.newSingleThreadExecutor();
            for (int i = 1; i < 11; i++) {
                //所有被内部类访问的局部变量,都必须使用final修饰
                //对于普通局部变量而言,当方法结束以后,该局部变量也就随之消失
                //但是匿名内部类的生命周期没有结束的话,将一直可以访问局部变量的值,内部类会扩大局部变量的作用域,会引发混乱
                final int index = i;
                executorService4.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Thread:" + index);
                    }
                });
            }

    七、其他知识点

    7.1、submit与execute的区别

    • submit支持Callable,execute支持Runable
    • submit有返回值,execute无返回值
    • submit可以捕获异常(还是因为支持Callable),execute不可以

    7.2、shutdown与shutdownNow的区别

    • shutdown()方法在终止前允许执行正在进行的线程
    • shutdownNow()方法阻止新的进程并试图停止当前正在执行的线程,关闭未使用的 ExecutorService 以允许回收其资源。
  • 相关阅读:
    中文字体
    URL锚点HTML定位技术机制
    关于JS异步加载方案
    select标签用法
    javascript refresh page 几种页面刷新的方法
    用JavaScript刷新框架子页面的七种方法
    robots.txt用法
    netstat 基本用法
    linux下ps命令
    socket编程和并发服务器
  • 原文地址:https://www.cnblogs.com/maikucha/p/8954274.html
Copyright © 2011-2022 走看看