谈谈线程池的使用

来源:互联网 发布:淘宝女式大衣 编辑:程序博客网 时间:2024/06/18 09:08

前言


首先,肯定要先说说,为什么要用那个线程池?

其实无论在计算机领域里面还是在人类社会里面,为了达到某个操作,创建另一资源以及销毁是消耗很大的。

我好像又不说人话了……文字概念解释总是比较难懂的……

这里写图片描述

这里写图片描述

故事看懂了吧?本灵魂画师说的就是这个故事,没有公司会这么做,因为一个员工是一个很重要的资源,不好招的。就像一个线程不好创建的,所以最好是平时搞个池子(公司/线程池)把它们装起来,要用的时候随时能用。这就是线程池的作用啦~

线程池是个怎样的结构体系


这里写图片描述

结构清晰明了,解释一下接口、实现类

Executor: 负责线程使用和调度的总接口
|– ExecutorService 线程池主接口
|– AbstractExecutorService 线程池抽象类
|– ThreadPoolExecutor 线程池实现类
|– ScheduleExecutorService 可调度的线程池接口
|– SchedulThreadPoolExecutor 可调度的线程池实现类

怎么用?


package com.pochi.juc;import java.util.concurrent.*;public class ThreadPoolProblem {    public static void main(String[] args) throws ExecutionException, InterruptedException {        // Executors是一个工具类,提供四种线程池        ExecutorService executorService = Executors.newFixedThreadPool(5);        // 从线程池开出10条线程        for (int i = 0; i < 10; i++) {            // 这就相当于start了,除了可以传Callable也可以传Runnable            Future<Integer> submit = executorService.submit(new ExecutorDemo());            // 把结果打印出来吧            System.out.println(submit.get());        }        // 注意关掉池子        executorService.shutdown();    }}class ExecutorDemo implements Callable<Integer> {    int sum;    @Override    public Integer call() throws Exception {        // 其实就是从1加到100操作        for (int i = 0; i < 100; i++) {            sum += i + 1;        }        // 打印出线程名        System.out.print(Thread.currentThread().getName()+"::");        return sum;    }}

结果

pool-1-thread-1::5050pool-1-thread-2::5050pool-1-thread-3::5050pool-1-thread-4::5050pool-1-thread-5::5050pool-1-thread-1::5050pool-1-thread-2::5050pool-1-thread-3::5050pool-1-thread-4::5050pool-1-thread-5::5050

如果加上了时间调度的线程池是咋样的呢?

这里是加了时间调度的线程池


所谓的时间调度,就是可以做延迟呀之类的。看看代码吧~

这里写图片描述

package com.pochi.juc;import java.time.LocalTime;import java.util.concurrent.*;public class ScheduleThreadPoolProblem {    public static void main(String[] args) throws ExecutionException, InterruptedException {        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);        // 这里介绍三个方法        // schedule(Callable/Runnable,延迟(一般填具体数字),延迟的单位是一天/一分钟还是...)        ScheduledFuture<Integer> schedule = scheduledExecutorService.schedule(new Callable<Integer>() {            Integer sum=0;            @Override            public Integer call() throws Exception {                for (int i = 0; i < 100; i++) {                    sum += i + 1;                }                return sum;            }        }, 1, TimeUnit.SECONDS);        System.out.println("schedule ::"+schedule.get());        // scheduleAtFixedRate(Runnable只能这个,初始化延迟,每次延迟间隔,延迟单位)        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println("scheduleAtFixedRate::"+LocalTime.now());            }        }, 1, 2, TimeUnit.SECONDS);        //scheduleWithFixedDelay(Runnable只能这个,初始化延迟,每次延迟间隔,延迟单位)        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println("scheduleWithFixedDelay::"+LocalTime.now());            }        }, 1, 2, TimeUnit.SECONDS);    }}

结果

schedule ::5050scheduleWithFixedDelay::22:17:22.411scheduleAtFixedRate::22:17:22.418scheduleAtFixedRate::22:17:24.269scheduleWithFixedDelay::22:17:25.414scheduleAtFixedRate::22:17:26.269scheduleAtFixedRate::22:17:28.269scheduleWithFixedDelay::22:17:28.415scheduleAtFixedRate::22:17:30.268scheduleWithFixedDelay::22:17:31.417scheduleAtFixedRate::22:17:32.269(一直不停的话,会继续下去)

看出什么问题

scheduleWithFixedDelay 和 scheduleAtFixedRate 有什么区别?看起来,方法参数都是一样的,返回值也是一样的。

注意分析结果

scheduleWithFixedDelay::22:17:22.411scheduleAtFixedRate::22:17:22.418scheduleAtFixedRate::22:17:24.269scheduleWithFixedDelay::22:17:25.414

看,其实,两者在里面都是有加入1s的sleep,但是两者的打印结果却是不同的,scheduleWithFixedDelay中,等那1s之后,才继续间隔2s,打印的。所以,两条输出之间的时间是3s间隔。而scheduleAtFixedRate两条打印之间的间隔是2s。

那么,那1s去哪儿了?

这里写图片描述

后记


这个线程池的解释还好吧?

原创粉丝点击