线程池三大方法、七大参数、四种拒绝策略

优化资源的使用 -->池化技术

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

池化技术:事先贮备好一些资源,要用,就来这里拿,用完之后还回来

线程池的好处:
降低资源的消耗
提高的响应速度
方便管理
线程复用,可以控制最大并发数、管理线程

一、三大方法
1、newSingleThreadExecutor() 单个线程

package com.han.demo01;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool {
    public static void main(String[] args) {
        ExecutorService ThreadPool1 = Executors.newSingleThreadExecutor();
        //ExecutorService ThreadPool2 = Executors.newFixedThreadPool(5);
        //ExecutorService ThreadPool3 = Executors.newCachedThreadPool();
        try {
            for (int i = 1; i <= 20; i++) {
                ThreadPool1.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "->执行");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ThreadPool1.shutdown();
        }
    }
}

在这里插入图片描述

2、newFixedThreadPool(int nThreads) 固定线程池大小

package com.han.demo01;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool {
    public static void main(String[] args) {
        //ExecutorService ThreadPool1 = Executors.newSingleThreadExecutor();
        ExecutorService ThreadPool2 = Executors.newFixedThreadPool(5);
        //ExecutorService ThreadPool3 = Executors.newCachedThreadPool();
        try {
            for (int i = 1; i <= 20; i++) {
                ThreadPool2.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "->执行");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ThreadPool2.shutdown();
        }
    }
}

在这里插入图片描述
3、newCachedThreadPool() 可伸缩的,遇强则强,遇弱则弱

package com.han.demo01;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool {
    public static void main(String[] args) {
        //ExecutorService ThreadPool1 = Executors.newSingleThreadExecutor();
        //ExecutorService ThreadPool2 = Executors.newFixedThreadPool(5);
        ExecutorService ThreadPool3 = Executors.newCachedThreadPool();
        try {
            for (int i = 1; i <= 20; i++) {
                ThreadPool3.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "->执行");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ThreadPool3.shutdown();
        }
    }
}

在这里插入图片描述
二、利用原生ThreadPoolExecutor自己创建线程池
在这里插入图片描述
三大方法的本质都是利用ThreadPoolExecutor创建线程池

创建线程池的七大参数

public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
                              int maximumPoolSize, //最大小线程池大小
                              long keepAliveTime, //存活时间,超时了没有调用就会释放
                              TimeUnit unit,//超时单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列
                              ThreadFactory threadFactory,//线程工厂,创建线程的,一般不用动
                              RejectedExecutionHandler handler //拒绝策略
                             ) {
        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;
    }

在这里插入图片描述
手动创建线程池:

package com.han.demo01;
import java.util.concurrent.*;

public class TestThreadPool {
    public static void main(String[] args) {
        ExecutorService ThreadPool = new ThreadPoolExecutor(
                2,
                5,
                3L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()//默认的拒绝策略,不处理该请求,并抛出异常
        );
        try {//最大承载:阻塞队列长度+maximumPoolSize,这里是8,那么第9个请求会使用拒绝策略处理
            for (int i = 1; i <= 9; i++) {
                ThreadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "->执行");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ThreadPool.shutdown();
        }
    }
}
pool-1-thread-1->执行
pool-1-thread-2->执行
pool-1-thread-1->执行
pool-1-thread-2->执行
pool-1-thread-1->执行
pool-1-thread-3->执行
pool-1-thread-4->执行
pool-1-thread-5->执行
java.util.concurrent.RejectedExecutionException: Task com.han.demo01.TestThreadPool$$Lambda$1/4952965@19a45b3 rejected from java.util.concurrent.ThreadPoolExecutor@99a589[Running, pool size = 5, active threads = 3, queued tasks = 0, completed tasks = 5]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
	at com.han.demo01.TestThreadPool.main(TestThreadPool.java:18)

只处理了8个请求,第9个请求没有处理,直接抛出异常。

三、四种拒绝策略
在这里插入图片描述

1. 队列满了,线程数达到最大线程数,还有线程过来,不处理这个线程,抛出异常
new ThreadPoolExecutor.AbortPolicy()
2. 哪里来的就去哪里,让调用线程去处理,比如这里的第9个请求会被主线程处理
new ThreadPoolExecutor.CallerRunsPolicy()
3. 队列满了,丢掉任务,不会抛出异常
new ThreadPoolExecutor.DiscardPolicy()
4. 队列满了,尝试和最早的竞争,竞争失败丢掉任务,也不会抛出异常
new ThreadPoolExecutor.DiscardOldestPolicy()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值