如何理解线程池中的参数设计

发布时间:2024年01月11日

如何理解线程池中的参数设计

  • 你的线程池的参数怎么配置?线程数量设置多少合理?
  • 如何确定一个线程池中的人物已经完成了
  • 为什么不建议使用java自带的Executors创建线程池
  • 线程池里面的阻塞队列设置多少合理?

考察:了解你对技术的掌握程度,|对于技术的理解、场景问题

线程池的参数有哪些

  • 核心线程数
    常驻在线程池中的工作线程数量
  • 最大线程数
    表示线程池中最大能容纳的线程数量(扩容)
  • 阻塞队列
    当核心线程跑满的时候,存储任务的容器
  • 等待时间
  • 等待时间单位
  • 拒接策略
    超过线程池能够处理的容量的时候的保护机制
  • 线程工厂

线程池的设计

池化技术->实现了对线程的复用(一个技术的产生背景)

  • 线程数量不可控
  • 线程的频繁创建和销毁带来的开销

ThreadPoolExector(Java实现)

通过生产者-消费者模型来解决线程服用问题(技术方案)
可以把基于阻塞队列的生产者消费者模型放大一下,就是分布式消息队列。
在这里插入图片描述

public class ThreadPoolDemo {
    static Queue<Runnable> tasks = new LinkedList<>();
    static class WorkThread implements Runnable {
        @Override
        public void run() {
            while (true) {
                Runnable task = tasks.poll();
                if (task != null) {
                    System.out.println("工作线程开始执行:" + Thread.currentThread().getName());
                    task.run();
                }else {
                    System.out.println("当前没有任务执行:" + Thread.currentThread().getName());
                    synchronized (WorkThread.class){
                        try {
                            WorkThread.class.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    
    public static void main(String[] args) {
        WorkThread workThread = new WorkThread();
        new Thread(workThread).start();
        Scanner scanner = new Scanner(System.in);
        while (true){
            String s = scanner.nextLine();
            tasks.add(()->{
                System.out.println(Thread.currentThread().getName()+"数据定时同步的任务,开始执行" + s);
            }) ;
            synchronized (WorkThread.class){
                WorkThread.class.notify();
            }
    
        }
     
    }
}

线程池的价值是什么?

架构思维

java开发,就真的只要会CRUD
职业发展-》架构,技术经理

  • 生产者消费模型(支付,第三方支付,异步发送到第三方支付)
  • 扩容和缩容的思想,工作线程的创建和销毁
  • 阻塞队列
  • 保护策略(拒绝策略),考虑系统的稳定性

Synchronized的锁升级

无锁-》偏向锁-〉轻量级锁-》重量级锁。

  • 什么是偏向锁,什么是轻量级锁,什么是重量级锁。
  • 为什么要设计锁升级?
  • Synchronized是提供了锁的公平性吗?
  • Synchronized锁标记怎么存储的?
  • 重量级锁为什么称为重量级锁?

java5之前,是没有锁升级这个概念的
无锁-》重量级锁
加锁会带来性能开销:

  • 内核指令的调用,涉及到上下文切换
  • 线程阻塞唤醒,涉及到上下文切换‘
    消耗cpu资源,影响程序的执行性能!
    加锁的方式从并行变成了串行。

两个层面的优化

使用层面的优化

控制加锁的位置,也就是锁的范围。

JVM层面的优化

1,编译器的优化,深度编译(锁的膨胀和锁的消除)
2,锁的升级

思考:能不能在让线程阻塞之前,就竞争到锁呢?
轻量级锁(自旋锁)
自旋竞争锁,通过循环尝试获取锁来竞争到锁资源。平衡循环次数
前提是:通过自旋尝试获得锁的代价,要比线程进入到阻塞代价更低

价值

提炼出有价值的架构思维
如何平衡好性能和安全性之间的关系

库存,防止超卖和少卖
ConcurrenthashMap 1.7的版本锁的是Segment,1.8版本锁的是Node节点
Mysql,表锁,行锁,间隙锁,临键锁,MVCC乐观锁

文章来源:https://blog.csdn.net/weixin_30409927/article/details/135531189
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。