线程池学习笔记

学习视频

线程池的好处

  1. 降低资源的消耗
  2. 提高响应的速度
  3. 方便管理
    线程复用,可以控制最大并发数,管理线程

线程池:三大方法

Executors

  1. Executors.newSingleThreadExecutor()
  2. Executors.newFixedThreadPool(num)
  3. Executors.newCachedThreadPool()
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo01 {
    public static void main(String[] args){
        ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
       // ExecutorService threadPool = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池
       // ExecutorService threadPool = Executors.newCachedThreadPool();//可伸缩的

        try {
            for (int i=0;i<10;i++){
                //使用线程池创建线程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //线程池关闭
            threadPool.shutdown();
        }
    }
}

七大参数

ThreadPoolExecutor中的

  1. corePoolSize 核心线程池大小
  2. maximumPoolSize 最大线程池大小
  3. keepAliveTime 超时无调用就会释放
  4. TimeUnit unit 超时单位
  5. BlockingQueue workQueue 阻塞队列
  6. ThreadFactory threadFactory 线程工厂,创建线程的,一般不用
  7. RejectedExecutionHandler handler 拒绝策略
public static ExecutorService newSingleThreadExecutor() {
        return new Executors.FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
    }

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    }

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
    }


public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
                          int maximumPoolSize,// 最大线程池大小
                          long keepAliveTime, //超时无调用就会释放
                          TimeUnit unit, //超时单位
                          BlockingQueue<Runnable> workQueue, //阻塞队列
                          ThreadFactory threadFactory,//线程工厂,创建线程的,一般不用
                          RejectedExecutionHandler handler//拒绝策略) {
        this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
        this.mainLock = new ReentrantLock();
        this.workers = new HashSet();
        this.termination = this.mainLock.newCondition();
        if (corePoolSize >= 0 && maximumPoolSize > 0 && maximumPoolSize >= corePoolSize && keepAliveTime >= 0L) {
            if (workQueue != null && threadFactory != null && handler != null) {
                this.corePoolSize = corePoolSize;
                this.maximumPoolSize = maximumPoolSize;
                this.workQueue = workQueue;
                this.keepAliveTime = unit.toNanos(keepAliveTime);
                this.threadFactory = threadFactory;
                this.handler = handler;
            } else {
                throw new NullPointerException();
            }
        } else {
            throw new IllegalArgumentException();
        }
    }

直接使用Executors创建线程池,可能会造成内存溢出,
因为FixedThreadPool和SingleThreadPool允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM;
CacheThreadPool和ScheduledThreadPool允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量线程,导致OOM。
建议最好使用ThreadPoolExecutor直接创建线程池

在这里插入图片描述
在这里插入图片描述

四种拒绝策略

在这里插入图片描述

import java.util.concurrent.*;

/**
 * ThreadPoolExecutor.AbortPolicy()  超出最大承载后直接抛出异常
 * ThreadPoolExecutor.CallerRunsPolicy() 让主线程运行
 * ThreadPoolExecutor.DiscardPolicy() 不抛出异常 丢掉任务
 * ThreadPoolExecutor.DiscardOldestPolicy() 队列满了尝试和最早进入的线程竞争,如果竞争失败丢弃,不抛异常
 */
public class Demo2 {
    public static void main(String[] args){
        //手动创建线程池
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                //new ThreadPoolExecutor.AbortPolicy());
                //new ThreadPoolExecutor.CallerRunsPolicy());
                new ThreadPoolExecutor.DiscardOldestPolicy());

        try {
            //最大承载 Depue+max
            //超出最大承载 AbortPolicy抛出异常
            for (int i=1;i<=9;i++){
                //使用线程池创建线程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //线程池关闭
            threadPool.shutdown();
        }
    }
}

最大线程数如何定义

  1. CPU密集型
    核数
    Runtime.getRuntime().availableProcessors()
  2. IO密集型
    判断程序中十分耗费IO的线程数量n,设置最大线程数大于n,最好为2n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值