多线程(六)线程池

一.环境

   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();//关闭线程池
    }

 同上,翻看源码

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

猜你喜欢

转载自www.cnblogs.com/wy0119/p/9011077.html