聊聊线程池

本文介绍了线程池的引入背景,以解决进程和线程创建销毁的开销问题。线程池通过预先创建线程并复用,提高了效率。标准库中,如`Executors.newFixedThreadPool()`可创建固定大小的线程池。此外,文章还展示了如何自定义线程池,包括使用`BlockingQueue`存储任务,以及`Worker`类和`ThreadPool`类的实现。
摘要由CSDN通过智能技术生成

1、线程池的引入背景 

       多进程是解决并发编程的方案,但是创建、销毁进程的开销很大;因此引入了线程,线程比进程要轻量很多,即便如此,如果在某些场景,需要频繁的创建销毁线程,那么此时创建销毁线程的开销也无法忽视了。为了解决这样的问题,引入线程池。

2、线程池的工作机制

        引入线程池之后,再去使用线程的时候,不是说用的时候再去创建,而是提前创建好,放到一个“池子里”,当我们需要使用线程的时侯,直接从池子里取一个线程过来,当我们不需要这个线程的时候,就把这个线程还回池子里,此时我们的操作就会比创建销毁线程效率更高。线程池最大的好处就是减少每次启动、销毁线程的损耗。

3、标准库中的线程池

使用 Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.

返回值类型为 ExecutorService

通过 ExecutorService.submit 可以注册一个任务到线程池中.

public static void main(String[] args) {
        //使用以下标准库中的线程池,先创建出一个线程池的实例
        ExecutorService service = Executors.newFixedThreadPool(10);
        //给这个实例里面加入一些任务
        service.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        });
    }

Executors 创建线程池的几种方式

newFixedThreadPool: 创建固定线程数的线程池

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

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

newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer. Executors 本质上是 ThreadPoolExecutor 类的封装.

4、实现线程池

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

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

使用一个 BlockingQueue 组织所有的任务 每个 worker 线程要做的事情: 不停的从 BlockingQueue 中取任务并执行.

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

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ThreadDemo28 {
    static class Worker extends Thread{
        private BlockingQueue<Runnable> queue = null;

        public Worker(BlockingQueue<Runnable> queue){
            this.queue = queue;
        }
        @Override
        public void run() {
            //工作线程的具体逻辑
            //需要从阻塞队列中取任务
            while (true){
                try {
                    Runnable command = queue.take();
                    //通过run来执行这个具体的任务
                    command.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    static class ThreadPool{
        //包含一个阻塞队列,用来组织任务
        private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

        //这个list就用来存放当前的工作线程
        private List<Thread> workers = new ArrayList<>();

        private static final int MAX_WORHKER_COUNT = 10;

        //通过这个方法,把任务加入到线程池中
        //submit不仅可以把任务放到阻塞队列中,同时也可以负责创建线程
        public void submit(Runnable command){
            if (workers.size() < MAX_WORHKER_COUNT){
                //如果当前工作线程的数量不足线程数目上限,就创建出新的线程
                //工作线程就专门搞一个类来完成
                //work内部要能够取到队列的内容,就需要把这个队列实例通过Work 的工作方法传过去
                Worker worker = new Worker(queue);
                worker.start();
                workers.add(worker);
            }
            queue.offer(command);

        }
    }
    public static void main(String[] args) {
        ThreadPool pool = new ThreadPool();
        for (int i = 0; i < 10; i++){
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello");
                }
            });
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值