zoukankan      html  css  js  c++  java
  • 多线程(六)线程池

    一.环境

       idea

    二.什么是多线程,使用多线程有什么好处

    有过数据库基础的应该了解过数据库连接池:作用是用来管理数据库连接

    线程池的作用与数据库连接池作用相同:是用来管理线程的

    2.1好处

    第一:降低源消耗。通重复利用已建的线程降低线建和造成的消耗。
    第二:提高响速度。当任到达,任可以不需要等到线建就能立即行。
    第三:提高线程的可管理性线程是稀缺源,如果无限制地建,不会消耗系统资源,
    会降低系定性,使用线程池可以一分配、调优控。

     

    三.多线程的几种创建方式

    在从jdk1.5以后,jdk为我们提供了并发包中的Executors来创建线程池

    3.1newCachedThreadPool(可缓存的线程池)

    创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程

     public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
    
            for (int i=0;i<10;i++){//创建10个线程
                final int temp=i;
                executorService.execute(new Runnable() {
                    public void run() {//线程调度的业务代码
                        System.out.println(Thread.currentThread().getName()+",i:"+temp);
                    }
                });
            }
            executorService.shutdown();//关闭线程池
        }

     由运行结果可以看出虽然使用代码创建了10个线程,但是实际却只创建了9个,说明有线程被复用了。翻看源码后。。。。

    打开ThreadPoolExecutor()方法发现,

    int corePoolSize,//创建线程池的核心线程数
    int maximumPoolSize,//创建线程池的最大线程数
    long keepAliveTime,//等待时间
    TimeUnit unit,//单位
    BlockingQueue<Runnable> workQueue//底层使用阻塞队列存储


    可以知道可缓存的线程池是没有创建核心线程池的,最大线程数等于int的最大值

    3.2 newFixedThreadPool (定长的线程池)

    创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

    public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(3);
    
            for (int i=0;i<10;i++){//创建10个线程
                final int temp=i;
                executorService.execute(new Runnable() {
                    public void run() {//线程调度的业务代码
                        System.out.println(Thread.currentThread().getName()+",i:"+temp);
                    }
                });
            }
            executorService.shutdown();//关闭线程池
        }

     由结果显示线程只有三个,那么是否就证明定长线程池就创建指定长度的线程数呢!!!!!查看源码

    发现源码调用了ThreadPoolExecutor()方法并将入参传递了下去



    所以可以得出结论定长线程池的线程池数量是固定的

    3.3 newFixedThreadPool (可定时的线程池)

    创建一个定长线程池,支持定时及周期性任务执行

    public static void main(String[] args) {
    
    
            ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
    
            for (int i=0;i<10;i++){//创建10个线程
                final int temp=i;
    
                scheduledExecutorService.schedule(new Runnable() {
                    public void run() {//线程调度的业务代码
                        System.out.println(Thread.currentThread().getName()+",i:"+temp);
                    }
                },3, TimeUnit.SECONDS);
            }
            scheduledExecutorService.shutdown();//关闭线程池
        }

     

    该效果是当程序运行了3秒后才调用。由于运行效果和定长差不多。所以看一下源码是不是也是只创建了3个线程。

    所以可以看出可定时的线程长度并不是指定长度,而是Int的最大值

     

    3.3 newSingleThreadExecutor (单线程的线程池)

    创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

    public static void main(String[] args) {
    
    
            ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    
            for (int i=0;i<10;i++){//创建10个线程
                final int temp=i;
    
                scheduledExecutorService.execute(new Runnable() {
                    public void run() {//线程调度的业务代码
                        System.out.println(Thread.currentThread().getName()+",i:"+temp);
                    }
                });
            }
            scheduledExecutorService.shutdown();//关闭线程池
        }

     同上,翻看源码

    由源码可知单线程的线程池只创建一个线程

  • 相关阅读:
    为什么会决定进行分库分表,分库分表过程中遇到什么难题,如何解决的?
    MySQL主从复制什么原因会造成不一致,如何预防及解决?
    PyQt5(2)、垃圾分类小程序(2)——初代窗口程序可执行文件
    垃圾分类小程序(1)——实现查找垃圾的类别
    python上的数据库sqlite3——插入多行数据
    pandas.DataFrame——pd数据框的简单认识、存csv文件
    Beautiful Soup 4.2.0 doc_tag、Name、Attributes、多值属性
    第一个爬虫——豆瓣新书信息爬取
    Decorator——Python初级函数装饰器
    正则表达式——字符类、分支条件、分组
  • 原文地址:https://www.cnblogs.com/wy0119/p/9011077.html
Copyright © 2011-2022 走看看