如何实现一个线程池1

线程池底层原理

1、什么是线程池

线程池和数据库连接池非常类似,可以统一管理和维护线程,减少没有必要的开销。

2、为什么使用线程池

​ 频繁的开启线程或者停止线程,线程需要重新被 cpu 从就绪到运行状态调度,需要发生 cpu 的上下文切换,效率非常低。

在阿里巴巴开发手册中也谈到,线程资源必须通过线程池提供,不允许在应用中自行显示创建线程

线程池的好处是减少在创建销毁线程上所消耗的时间和系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题

3、线程池有哪些作用

统一管理线程,核心就是复用机制(线程池通过提前创建几个线程一直在运行状态,限制好了线程的数目)

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

4、线程池底层如何是如何实现复用的

手写线程池-- 多线程的思想、生产者消费者模型

  1. 阻塞队列
  2. 线程池封装(核心思想为复用机制)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Lx58Vte-1666537321142)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml12084\wps1.jpg)]

做只会创建2个线程,提交10个线程任务(涉及到缓存)

  1. 定义一个容器LinkedBlockingQueue缓存提交的线程任务
  2. 提前创建好固定数量的线程一直在运行状态(5个线程)
  3. 无界(无限存储)有界(有限制容量存储元素)
  4. 提交线程任务放在LinkedBlockingQueue中缓存起来
  5. 一直在运行的线程就会从LinkedBlockingQueue获取线程任务执行
public class BeauExecutors {
    //1. 定义一个容器LinkedBlockingQueue缓存提交的线程任务
    private LinkedBlockingDeque<Runnable> runnables;

    /**
     *
     * @param queSize 队列缓存任务容量的大小
     * @param runThreadCount 运行线程个数
     */
    public BeauExecutors(int queSize,int runThreadCount){
        runnables=new LinkedBlockingDeque<>(queSize);
        for(int i=0;i<runThreadCount;i++){
            new TaskThread().start();
        }
    }

    /**
     * 提交线程任务
     * @param target
     */
    void execute(Runnable target){
        runnables.offer(target);

    }

    class TaskThread extends Thread{
        @Override
        public void run() {
            //线程一直在运行
            while(true){
            //5. 一直在运行的线程就会从LinkedBlockingQueue获取线程任务执行
                Runnable poll = runnables.poll();
                if(poll!=null){
                    poll.run();
                }
            }
        }
    }
}

5、如何停止线程池

定义一个boolean类型的变量进行控制

    //标记停止线程
    private volatile boolean isRun=true;

    //停止当前线程池,
    public void shutdown(){
        isRun=false;
    }

    class TaskThread extends Thread{
        @Override
        public void run() {
            //这里可以保障任务队列的全部任务全部运行完在关闭线程池
            while(isRun||runnables.size()>0){
                Runnable poll = runnables.poll();
                if(poll!=null){
                    poll.run();
                }
            }
        }
    }

我们在运行的时候出现CPU飙高的情况

解决CPU飙高

new Thread(()->{
   while (true){ //CPU飙高
       Thread.sleep(10); //加上sleep不会发生CPU飙高
   }
}).start();

//so
class TaskThread extends Thread{
       @Override
       public void run() {
           //这里可以保障任务队列的全部任务全部运行完在关闭线程池
           while(isRun||runnables.size()>0){
               Runnable poll = runnables.poll(3, TimeUnit.SECONDS);
               if(poll!=null){
                   poll.run();
               }
           }
       }
   }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值