【多线程】-- 线程池

线程池

线程池也是一种多线程模式,特点在于可以根据需求创建线程池,线程池的线程直接执行任务。


线程池的优点🎯

复用:线程与任务是分离的,所以一个线程可以执行多个任务。

资源: 线程池中的线程一直处于RUNNABLE状态去获取任务,不会立即被销毁,减少了创建和销毁线程带来的资源开销。

可管理: 线程池会根据任务再去创建或者销毁线程,避免大量的线程被创建和销毁。

速度: 由于线程已经准备好了,只要有任务线程就可以立即执行,减少了创建和启动的时间。


创建线程池🎯

Java标准库提供了创建线程池的接口Executers,它只是用来创建线程池,而线程池的接口是ExecuterService。Executors类里面提供了一些静态工厂,生成一些常用的线程池。

	// 1. 可以缓存线程的线程池,用来处理大量短时间工作任务的线程池,如果池中没有可用的线程将创建新的线程,如果线程空闲60秒将收回并移出缓存
	ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    // 2. 创建一个操作无界队列(LinkedBlockingQueue)且固定大小线程池
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(n);
    // 3. 创建一个操作无界队列且只有一个工作线程的线程池
    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    // 4. 创建一个单线程执行器,可以在给定时间后执行或定期执行。
    ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();

除了newScheduledThreadPool的内部实现特殊一点之外,其它线程池内部都是基于ThreadPoolExecutor类(Executor的子类)实现的。

ThreadPoolExecutor创建线程池,它的构造方法提供了很多参数,可以自定义的设置想要的线程池。它提供了四种构造方法,下面是最全参数的一种,其他三种只是最后两个参数区别。

ThreadPoolExecutor(int corePoolSize, // 核心线程数
                   int maximumPoolSize,// 最大线程数 
                   long keepAliveTime, // 非核心线程的空闲存活时间
                   TimeUnit unit, // 存活时间的计量单位
                   BlockingQueue<Runnable> workQueue, // 组织任务的阻塞队列
                   
                   ThreadFactory threadFactory, // 辅助创建线程的线程工厂
                   RejectedExecutionHandler handler // 执行任务失败处理器,拒绝策略
                  ) 

RejectedExecutionHandler拒绝策略是指线程池满了,那么继续添加任务采取的拒绝方法拒绝策略也提供了四种

ThreadPoolExecutor.AbortPolicy // 直接抛出异常
ThreadPoolExecutor.CallerRunsPolicy // 哪个线程添加的则哪个线程执行这个任务
ThreadPoolExecutor.DiscardOldestPolicy // 把队列中最老(最先入队)的任务丢弃
ThreadPoolExecutor.DiscardPolicy // 丢弃这个添加的任务(最新)

线程池的工作流程🎯

工作流程


模拟实现线程池🎯

模拟一个设置固定大小的线程池

class ThreadPool{
	// 组织任务
	private BlockingDeque<Runnable> blockingDeque = new LinkedBlockingDeque<>();

    // 添加任务
	public void submit(Runnable runnable) throws InterruptedException {
        blockingDeque.put(runnable);
    }

    // 设置线程池
	public ThreadPool(int n) {
        for(int i = 0;i < n;i++) {
            // 每个线程的任务是一直从阻塞队列获取任务,拿到就执行。
            Thread t = new Thread(() -> {
                while (true) {
                    try {
                        Runnable runnable = blockingDeque.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值