线程池 ---线程池的创建及ThreadPoolExecutor的七个参数

1.线程池是什么?

线程池(ThreadPool)是⼀种基于池化思想管理和使⽤线程的机制。它是将多个线程预先存储在⼀个“池⼦”内,当有任务出现时可以避免重新创建和销毁线程所带来性能开销,只需要从“池⼦”内取出相应的线程执⾏对应的任务即可。

2.为什么要用线程池?

1. 降低资源消耗:通过池化技术重复利⽤已创建的线程,降低线程创建和销毁造成的损耗。
2. 提⾼响应速度:任务到达时,⽆需等待线程创建即可⽴即执⾏。
3. 提⾼线程的可管理性:线程是稀缺资源,如果⽆限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使⽤线程池可以进⾏统⼀的分配、调优和监控。

3.线程池使用

总的来说分为两类:
1.通过ThreadPoolExecutor 创建的线程池;
2.通过Executors 创建的线程池。
以下  6 种是通过 Executors 创建的:
1. Executors.newFixedThreadPool:创建⼀个固定⼤⼩的线程池,可控制并发的线程数,超出的线程会在队列中等待;
ExecutorService threadPool = Executors.newFixedThreadPool(2);
// 添加任务⽅式 1
threadPool.submit(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
   }
});
// 添加任务⽅式 2
threadPool.execute(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
   }
});

2. Executors.newCachedThreadPool:创建⼀个可缓存的线程池,若线程数超过处理所需,缓存⼀段时间后会回收,若线程数不够,则新建线程;
ExecutorService threadPool =
Executors.newCachedThreadPool(threadFactory);

3. Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执⾏顺序;
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 执⾏普通⽅法
threadPool.submit(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
   }
});

4. Executors.newScheduledThreadPool:创建⼀个可以执⾏延迟任务的线程池;
ScheduledExecutorService threadPool =
                Executors.newScheduledThreadPool(10);
// 定时任务
System.out.println("设置定时任务:" + new Date());
// 延迟 n 秒后执⾏(只执⾏⼀次)
threadPool.schedule(new Runnable() {
    @Override
    public void run() {
        System.out.println("schedule:" + new Date());
   }
}, 2, TimeUnit.SECONDS);

5. Executors.newSingleThreadScheduledExecutor:创建⼀个单线程的可以执⾏延迟任务的线程
池;
ScheduledExecutorService threadPool =
                Executors.newSingleThreadScheduledExecutor();
// 定时任务
System.out.println("设置定时任务:" + new Date());
// 延迟 n 秒后执⾏(只执⾏⼀次)
threadPool.schedule(new Runnable() {
    @Override
    public void run() {
        System.out.println("schedule:" + new Date());
   }
}, 2, TimeUnit.SECONDS);

6. Executors.newWorkStealingPool:根据当前CPU⽣成线程池
ExecutorService threadPool = Executors.newWorkStealingPool();
// 执⾏普通⽅法
for (int i = 0; i < 100; i++) {
    int count = i;
    threadPool.submit(new Runnable() {
        @Override
        public void run() {
            System.out.println(count + "," +
                               Thread.currentThread().getName());
       }
   });
}
while (!threadPool.isTerminated()) {
}
Executors 缺陷:⾃动创建线程池可能会导致OOM

4.ThreadPoolExecutor 使⽤

4.1 ThreadPoolExecutor 参数说明

1. corePoolSize:所谓的核⼼线程数,可以⼤致理解为⻓期驻留的线程数⽬
2. maximumPoolSize:顾名思义,就是线程不够时能够创建的最⼤线程数。
3. keepAliveTime:空闲线程的存活时间,如果线程的空闲时间超过这个值,那么将会被关闭。注意此值⽣效条件必须满⾜:空闲时间超过这个值,并且线程池中的线程数少于等于核⼼线程数
corePoolSize,当然核⼼线程默认是不会关闭的
4. TimeUnit:时间单位。
5. BlockingQueue:任务队列,⽤于存储线程池的待执⾏任务的。
6. threadFactory:⽤于⽣成线程,⼀般我们可以⽤默认的就可以。
7. handler:当线程池已经满了,但是⼜有新的任务提交的时候,该采取什么策略由这个来指定。有⼏ 种⽅式可供选择,像抛出异常、直接拒绝然后返回等,也可以⾃⼰实现。

4.2ThreadPoolExecutor 使用

 //自定义线程工厂
    ThreadFactory threadFactory=new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread thread=new Thread(r);
            thread.setName("name"+r.hashCode());
            thread.setPriority(Thread.MAX_PRIORITY);
            return thread;
        }
    };
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10,10,60, TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100), threadFactory,new ThreadPoolExecutor.AbortPolicy());
    threadPool.submit(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    });

4.3线程池执行流程

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值