java线程池:3大方法、7大参数、4种拒绝策略

池化技术

程序的运行,本质:占用系统的资源! (优化资源的使用 => 池化技术)

线程池、连接池、内存池、对象池///… 创建、销毁。十分浪费资源

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。

线程池好处

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

三大方法

import java.util.concurrent.ExecutorService;
import java.util.List;
import java.util.concurrent.Executors;
public class Demo01 {
    public static void main(String[] args) {
        // Executors 工具类、3大方法
        // Executors.newSingleThreadExecutor();// 创建单个线程的线程池
        // Executors.newFixedThreadPool(5);// 创建一个固定大小的线程池
        // Executors.newCachedThreadPool();// 创建一个可伸缩的线程池
        // 单个线程的线程池
        ExecutorService threadPool =     
                                Executors.newSingleThreadExecutor();
        try {
            for (int i = 1; i < 100; i++) {
                // 使用了线程池之后,使用线程池来创建线程
                threadPool.execute(()->{
                    System.out.println(
                        Thread.currentThread().getName()+" ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }
    }
}

newSingleThreadExecutor() 创建单个线程的线程池
newFixedThreadPool(5) 创建一个固定大小的线程池
newCachedThreadPool(); 创建一个可伸缩的线程池

7大参数

源码分析中

// 本质ThreadPoolExecutor() 
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小 
                          int maximumPoolSize, // 最大核心线程池大小 
                          long keepAliveTime, // 超时没有人调用就会释放 
                          TimeUnit unit, // 超时单位 
                          // 阻塞队列 
                          BlockingQueue<Runnable> workQueue, 
                          // 线程工厂:创建线程的,一般 不用动
                          ThreadFactory threadFactory,  
                          // 拒绝策略
                          RejectedExecutionHandler handle ) {
    if (corePoolSize < 0 
        || maximumPoolSize <= 0 
        || maximumPoolSize < corePoolSize 
        || keepAliveTime < 0) 
        throw new IllegalArgumentException(); 
    if (workQueue == null 
        || threadFactory == null 
        || handler == null) 
        throw new NullPointerException(); 
    this.acc = System.getSecurityManager() == null 
        ? null : AccessController.getContext(); 
    this.corePoolSize = corePoolSize; 
    this.maximumPoolSize = maximumPoolSize; 
    this.workQueue = workQueue; 
    this.keepAliveTime = unit.toNanos(keepAliveTime); 
    this.threadFactory = threadFactory; 
    this.handler = handler; 
}

因为实际开发中工具类Executors 不安全,所以需要手动创建线程池,自定义7个参数。

Executors 在FixedThreadPool 和 SingleThreadPool中 允许的请求队列长度为integer.MAX_VALUE

== 时,会出现大量堆积请求,从而导致OOM(内存溢出) ==

在CachedThreadPool 和 ScheduledThreadPool中 允许的创建线程数量为integer.MAX_VALUE时,

== 会出现大量堆积请求,从而导致OOM(内存溢出) ==

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
// Executors 工具类、3大方法
// Executors.newSingleThreadExecutor();// 创建一个单个线程的线程池
// Executors.newFixedThreadPool(5);// 创建一个固定大小的线程池
// Executors.newCachedThreadPool();// 创建一个可伸缩的线程池
/**
 * 四种拒绝策略:
 *
 * new ThreadPoolExecutor.AbortPolicy() 
 * 银行满了,还有人进来,不处理这个人的,抛出异常
 *
 * new ThreadPoolExecutor.CallerRunsPolicy() 
 * 哪来的去哪里!比如你爸爸正在做的饭 让你去通知妈妈做饭,妈妈拒绝,让你回去通知爸爸做饭,就是交给原来线程处理
 *
 * new ThreadPoolExecutor.DiscardPolicy() 
 * 队列满了,丢掉任务,不会抛出异常!
 *
 * new ThreadPoolExecutor.DiscardOldestPolicy() 
 * 队列满了,尝试去和最早的竞争,也不会抛出异常!
 */
public class Demo01 {
    public static void main(String[] args) {
        // 自定义线程池!工作 ThreadPoolExecutor
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,// int corePoolSize, 核心线程池大小(候客区窗口2个)
                5,// int maximumPoolSize, 最大核心线程池大小(总共5个窗口) 
                3,// long keepAliveTime, 超时3秒没有人调用就会释,放关闭窗口 
                TimeUnit.SECONDS,// TimeUnit unit, 超时单位 秒 
                new LinkedBlockingDeque<>(3),// 阻塞队列(候客区最多3人)
                Executors.defaultThreadFactory(),// 默认线程工厂
                // 4种拒绝策略之一:
                // 队列满了,尝试去和 最早的竞争,也不会抛出异常!
                new ThreadPoolExecutor.DiscardOldestPolicy());  
        //队列满了,尝试去和最早的竞争,也不会抛出异常!
        try {
            // 最大承载:Deque + max
            // 超过 RejectedExecutionException
            for (int i = 1; i <= 9; i++) {
                // 使用了线程池之后,使用线程池来创建线程
                threadPool.execute(()->{
                    System.out.println(
                        Thread.currentThread().getName()+" ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }
    }
}

4种拒绝策略

  • new ThreadPoolExecutor.AbortPolicy()
  • 银行满了,还有人进来,不处理这个人的,抛出异常
  • new ThreadPoolExecutor.CallerRunsPolicy()
  • 哪来的去哪里!比如你爸爸正在做的饭 让你去通知妈妈做饭,妈妈拒绝,让你回去通知爸爸做饭,就是交给原来线程处理
  • new ThreadPoolExecutor.DiscardPolicy()
  • 队列满了,丢掉任务,不会抛出异常!
  • new ThreadPoolExecutor.DiscardOldestPolicy()
  • 队列满了,尝试去和最早的竞争,也不会抛出异常!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值