线程池基本参数和拒绝策略

11 篇文章 0 订阅
2 篇文章 0 订阅

java-code: java代码管理 (gitee.com)

文章目录

一、线程池是什么

二、为什么从线程池里拿线程就比从系统创建快呢?

三、简单使用库里提供的线程池~

四、Executors 创建线程池的几种方式

五、线程池的参数介绍

六、模拟实现线程池

总结


一、线程池是什么

线程池就是提前把线程准备好,创建线程不是直接从系统中申请了,而是从池子那个那,用完了再还给池子。

为什么要有线程池呢??

虽然我们说线程是轻量化的,但是如果数量特别多,而且频繁创建,那么这个开销也是不可忽视的~  线程池的最大好处就是减少每次启动,销毁线程的损耗~

二、为什么从线程池里拿线程就比从系统创建快呢?

我们从线程池拿线程,就是纯粹的用户态操作~

从系统创建线程,就要设计到用户态和内核态的转换了~      

举例说明:

假如你要去复印店复印文件~有很多人都在,此时你有两种选择,

第一张是找老板,告诉他我要复印什么,老板说知道了,然后就去了,但是老板还有很多其他的事情,他可能不是第一时间就给你打印,可能是先给先来的打印了,或者上了个厕所~(此时的老板就是内核)

第二种是:你自己去复印的电脑哪里自己打印,你自己就只有一个任务,就直接给自己打印就完事 了~(用户态)  所以说线程池拿取线程和销毁都比直接从系统操作要快~

三、简单使用库里提供的线程池~

 这样就可以使用线程池来进行线程的创建和销毁~

那么这里为什么不是直接new一个线程池呢??

这就是构造方法留下的坑了

我们知道在JAVA里,有构造方法来描述对象,并初始化,我们可以通过重载来实现一个多个多个描述,但是如果参数完全相同就无法构成重载,万一你两种描述的参数就是一模一样的,这就很蛋疼了~这就没办法了,所以就只能使用工厂模式(专门创建一个类来构造方法)来解决~

四、Executors 创建线程池的几种方式

1.newFixedThreadPool:创建固定线程数的线程池(输入十个就是创建十个线程)

2.newCachedThreadPool: 创建线程数动态增长的线程池~

3.newSingleThreadExecutor:创建只包含一个线程的线程池

4.newScheduledThreadPool:周期性线程池,可以设定延迟时间执行命令(类似定时器)

五、线程池的参数介绍

 这是JAVA官方给出的线程池参数:

1.corePoolSize:核心线程数   (真正的核心有几个线程)

2.maximumPoolSize:最大线程数   (线程池当任务比较多的时候,就会创建一些临时线程来帮助完成工作(不会超过最大线程),当任务少了之后就会自动销毁)
3.keepAliveTime:临时线程存活的最大时间(当任务少了之后并不会立刻销毁,如果不再出现大量任务,就根据这个时间,到时间就自动销毁,)
4.   TimeUnit unit :线程存活时间的单位(是秒还是毫秒等等)

5. BlockingQueue< Runnable> workQueue:线程池线程存放的阻塞队列(程序员可以手动指定)
6. ThreadFactory threadFactory:工厂模式,创建线程辅助的类
7. RejectedExecutionHandler handler:线程池的拒绝策略 (如果线程池满了,再添加的应对策略)
(拒绝策略详情)
ThreadPoolExecutor.AbortPolicy:直接抛异常,如果线程池满了,再添加就直接结束线程池运行,并抛出异常(新任务和原来的任务都没有继续运行了)
ThreadPoolExecutor.CallerRunsPolicy:添加的线程,自己取执行这个任务(自己添加的线程,自己去执行,线程池还是原来的任务)
ThreadPoolExecutor.DiscardOldestPolicy:丢弃老的任务(也就是马上要执行的任务)(直接删除了),执行新加入的线程  
ThreadPoolExecutor.DiscardPolicy:丢弃新的任务,继续执行线程(也就是你新的线程要进线程池,直接拒绝,然后继续执行原来的线程)

六、模拟实现线程池

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

class MyThreadpool{
            private BlockingDeque<Runnable> queue=new LinkedBlockingDeque<>();  //阻塞队列
            public void submit(Runnable runnable) throws InterruptedException {
                queue.put(runnable);  //把任务放到阻塞队列
            }
            public MyThreadpool(int n){  //模拟固定线程数量的线程池
                for (int i = 0; i <n; i++) {
                    Thread t=new Thread(()->{
                        try {
                            while (true) {   //要让线程不停的取任务
                                Runnable runnable = queue.take();
                                runnable.run();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    });
                    t.start();
                }
            }
        }
public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        MyThreadpool pool=new MyThreadpool(10);
        for (int i = 0; i <1000; i++) {
            int number=i;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello"+number);
                }
            });
        }
    }
}

 线程就会执行打印一千次(并发执行)~


总结

介绍了 线程池的基本参数,如何使用Executors 创建线程池,模拟实现线程池,还有很多不足之处,老铁们多多指教~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值