【多线程基础】线程池

目录

一、线程池是什么

二、标准库中的线程池

2.1 标准库创建线程的几种方式

2.2 创建线程池和创建对象的对比

2.3 ThreadPoolService

2.4 线程拒绝策略(handler)

 三、手动实现一个线程池


一、线程池是什么

        线程池主要功能就是提升程序的执行效率的,为了减少冗余的创建,就是减少每次启动、销毁线程的损耗。

二、标准库中的线程池

2.1 标准库创建线程的几种方式

public class ThreadDemo17 {
    public static void main(String[] args) {
        //创建固定线程数的线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        //创建线程数目动态增长的线程池
        ExecutorService pool1 = Executors.newCachedThreadPool();
        //创建只包含单个线程的线程池
        ExecutorService pool2 = Executors.newSingleThreadExecutor();
        //设定延迟事件后执行命令,也就是设置一个带定时器功能的线程池
        ExecutorService pool3 = Executors.newScheduledThreadPool(10);
    }
}

2.2 创建线程池和创建对象的对比

        创建线程池采用了工厂模式,用了ExecutorService的静态方法,因为不用这种方法的话,如果都传两个参数,编译器无法分辨线程池的特性,而采用工厂模式的话就可以随用随取。

2.3 ThreadPoolService

        java中提供了线程池的相关标准ThreadPoolService

 介绍下这个方法的相关参数:

corePoolSize:表示核心线程数

maximumPoolSize:最多线程数(可以存在临时线程,但是核心线程数和临时线程数之和有一个界限)

keepAliveTime:非核心线程数存活的最大等待时间

unit:keepAliveTime的时间单位

workQueue:线程池的任务队列

threadFactory:线程工厂 线程创建的方案

handler:拒绝策略 描述如果当前任务队列任务满了,以什么方式拒绝

2.4 线程拒绝策略(handler)

 ThreadPoolExecutor.AbortPolicy :如果任务队列中的任务满了,如果再添加任务,直接抛出异常RejectedExecutionException

举一个例子:如果老师给你布置了很多任务,还想给你再添加一个任务,你受不了了,直接哭了出来。


ThreadPoolExecutor.CallerRunsPolicy:如果任务队列中的任务满了,再添加任务,谁添加的谁负责

举一个例子:如果老师给你布置了很多任务,还想给你再添加一个任务,你说你再添加你自己去做,我不做。


ThreadPoolExecutor.DiscardOldestPolicy:如果任务队列中的任务满了,再添加任务,我就会丢弃最老的任务,把新的任务添加进来

举一个例子:如果老师给你布置了很多任务,还想给你再添加一个任务,我会先把时间最早的任务丢弃,把最新的任务添加进来。


ThreadPoolExecutor.DiscardPolicy:如果任务队列中的任务满了,再添加任务,就丢弃要添加的任务

举一个例子:如果老师给你布置了很多任务,还想给你再添加一个任务,你直接无视他新布置的任务。

 三、手动实现一个线程池

1、使用一个Worker类描述一个工作线程,使用Runnable描述一个任务

2、线程池的核心操作为submit,将任务加入线程池中

3、使用一个阻塞队列(BlockingQueue)组织所有任务

4、每个worker线程要做的任务:不停的从BlockingQueue中去任务并执行

5、指定一下线程池的最大线程数,当当前线程数超过这个最大值时,就不再新增线程了

class Worker {
    //使用阻塞队列来组织任务
    BlockingQueue<Runnable> queue = new LinkedBlockingDeque<>(100);

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

    //实现一个固定线程数的线程池
    public Worker(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 ThreadDemo18 {
    public static void main(String[] args) throws InterruptedException {
        Worker worker = new Worker(10);
        for (int i = 0; i < 1000; i++) {
            int number = i;
            worker.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + number);
                }
            });
        }
    }
}

运行结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值