2024最新一线互联网大厂常见高并发面试题解析

本文深入探讨Java高并发面试中的常见问题,涵盖线程池的工作原理、核心参数解析,以及Atomic关键字的应用。讨论了线程的创建方式、run()与start()的区别、线程优先级的理解,还提供了线程安全的单例模式实现。此外,文章提及了线程同步中的wait-notify机制,并通过生产者-消费者问题展示了其实现。最后,文章提及了多线程环境下的伪共享问题,强调了在并发编程中需要注意的性能优化细节。
摘要由CSDN通过智能技术生成
  1. Entry 的 Key 是一个 ThreadLocal 实例,Value 是一个线程特有对象。Entry 的作用即是:为其属主线程建立起一个 ThreadLocal 实例与一个线程特有对象之间的对应关系;

  2. Entry 对 Key 的引用是弱引用;Entry 对 Value 的引用是强引用。

6)线程池有了解吗?(必考)

答:java.util.concurrent.ThreadPoolExecutor 类就是一个线程池。客户端调用 ThreadPoolExecutor.submit(Runnable task) 提交任务,线程池内部维护的工作者线程的数量就是该线程池的线程池大小,有 3 种形态:

  • 当前线程池大小 :表示线程池中实际工作者线程的数量;
  • 最大线程池大小 (maxinumPoolSize):表示线程池中允许存在的工作者线程的数量上限;
  • 核心线程大小 (corePoolSize ):表示一个不大于最大线程池大小的工作者线程数量上限。
  1. 如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队;

  2. 如果运行的线程等于或者多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不是添加新线程;

  3. 如果无法将请求加入队列,即队列已经满了,则创建新的线程,除非创建此线程超出 maxinumPoolSize, 在这种情况下,任务将被拒绝。

面试官:我们为什么要使用线程池?

答:

  1. 减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

  2. 可以根据系统的承受能力,调整线程池中工作线程的数目,放置因为消耗过多的内存,而把服务器累趴下(每个线程大约需要 1 MB 内存,线程开的越多,消耗的内存也就越大,最后死机)

面试官:核心线程池内部实现了解吗?

答:对于核心的几个线程池,无论是 newFixedThreadPool() 方法,newSingleThreadExecutor() 还是 newCachedThreadPool() 方法,虽然看起来创建的线程有着完全不同的功能特点,但其实内部实现均使用了 ThreadPoolExecutor 实现,其实都只是 ThreadPoolExecutor 类的封装。

为何 ThreadPoolExecutor 有如此强大的功能呢?我们可以来看一下 ThreadPoolExecutor 最重要的构造函数:

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler)

函数的参数含义如下:

  • corePoolSize:指定了线程池中的线程数量

  • maximumPoolSize:指定了线程池中的最大线程数量

  • keepAliveTime:当线程池线程数量超过 corePoolSize 时,多余的空闲线程的存活时间。即,超过了 corePoolSize 的空闲线程,在多长时间内,会被销毁。

  • unit: keepAliveTime 的单位。

  • workQueue:任务队列,被提交但尚未被执行的任务。

  • threadFactory:线程工厂,用于创建线程,一般用默认的即可。

  • handler:拒绝策略。当任务太多来不及处理,如何拒绝任务。

7)Atomic关键字:

答:可以使基本数据类型以原子的方式实现自增自减等操作。参考博客:concurrent.atomic包下的类AtomicInteger的使用

8)创建线程有哪几种方式?

答:有两种创建线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创建一个Thread对象;二是直接继承Thread类。

面试官:两种方式有什么区别呢?

  1. 继承方式:
  • (1)Java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了.

  • (2)从操作上分析,继承方式更简单,获取线程名字也简单.(操作上,更简单)

  • (3)从多线程共享同一个资源上分析,继承方式不能做到

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值