栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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()));
    }

2、在进入new ThreadPoolEXecutor类中

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

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

七大参数概述
int corePoolSize核心线程池大小
int maximumPoolSize最大线程池大小
long keepAliveTime超时没调用就释放
TimeUnit unit超时单位
BlockingQueue 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倍就好

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/530745.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号