JAVA线程池的三大创建方式和七大参数

一、线程池的概念

           1、为什么使用线程池

                 程序的运行本质是占用系统资源,系统资源是有限的,所以我们要优化资源的使用!就             出现了池化技术

           2、什么是线程池

                可以理解为事先准备好一些资源,要有人用就来池里面拿着。用完后在放到池中。        

二、线程池的好处

           1、降低资源的消耗

           2、提高响应的速度

           3、方便管理

           总:线程复用,可以控制最大并发数,管理线程

三、线程池的创建

线程的创建有三种方法,使用Executors类中有三个实现方法

newSingleThreadExecutor()单线程
newFixedThreadPool()固定线程池
newCachedThreadPool()可伸缩的线程池

代码:

package com.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//线程池
public class pool {
    public static void main(String[] args) {
        ExecutorService threadPool1 = Executors.newSingleThreadExecutor();//单个线程
        ExecutorService threadPool2 = Executors.newFixedThreadPool(5);//固定线程池大小
        ExecutorService threadPool3 = Executors.newCachedThreadPool();//可伸缩的线程池
        try {
            for (int i = 0; i < 5; i++) {
                final int sum = i;
                threadPool1.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"-------"+sum);
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool1.shutdown();
        }
    }
}


四、七大参数

  举例理解七大参数

现在有一家火锅店里面有9个座位(看成是最大核心线程池大小),外面有3把等候的椅子(队列)。平常火锅店里的人不多,所以就只开放5个座位(看成是核心线程池大小),今天是周六来火锅店吃饭的人特别多,里面的5个座位都坐满了(等于核心线程池大小),外面等候区的3个椅子也满了(队列)。这时候又来了一个人,座位6就会被开发使用,又加一个人的时候,座位7也可以使用,一直到座位9个都开放(达到了最大核心线程池大小),外面等候区3个人也都满了。这时候又来了一位顾客,他等待一会(超时等待)如果前面还是没位置,那么他就到别的地方去了(释放掉)。

1、线程池创建的本质是:ThreadPoolExecutor

点击进入源码就能知道

源码的代码如下:

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

2、在进入new ThreadPoolEXecutor类中

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

3、可以看到创建线程池的七大参数

七大参数概述
int corePoolSize核心线程池大小
int maximumPoolSize最大线程池大小
long keepAliveTime超时没调用就释放
TimeUnit unit超时单位
BlockingQueue<Runnable> workQueue阻塞队列
Executors.defaultThreadFactory()线程工厂(一般不用改变)
defaultHandler拒绝策略

4、在我们日常工作中,线程池是不允许使用Executors创建的,而是通过ThreadPoolExecutor的方式创建,规避资源耗尽的风险;

Executors创建线程池,允许创建的线程池为Integer.Max_Value,约为21亿

可能创建大量线程,从而导致OOM


五、自定义线程池

1、一般推荐使用自定义线程池

代码:

package com.pool;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//自定义线程池
public class DIYPool {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,    //核心线程池大小
                5,//最大核心线程池大小
                2,   //超时时间
                TimeUnit.SECONDS,   //超时单位
                new LinkedBlockingDeque<>(3), //阻塞队列
                Executors.defaultThreadFactory(),      //线程工厂
                new ThreadPoolExecutor.DiscardPolicy() //拒绝策略
        );
        try {
            for(int i=1;i<=10;i++){
                threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPoolExecutor.shutdown();
        }
    }
}

2、拒绝策略分为4种

                       new  ThreadPoolExecutor

.AbortPolicy()队列满了,丢掉任务,抛出异常
.CallerRunsPolicy()哪里来到哪里去
.DiscardPolicy()队列满了,丢掉任务,不抛异常
.DiscardoldestPolicy()队列满了,尝试去和最早的竞争,无异常


六、最大核心线程池大小该如何定义(扩展)

    1、cpu密集型

            查看电脑cpu是几何最大线程就是几,可以保持cpu的效率最高

           获取cpu的核数:

Runtime.getRuntime().availableProcessors()

    2、Io密集型

          判断程序中十分耗Io的线程,一般大于Io线程的2倍就好

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值