Java多线程面试题及答案(最新版)

Java面试题及答案(2022版),适用于应届生、有工作经验的程序员,每道都是认真筛选出的高频面试题,助力大家能找到满意的工作!

Java多线程

下载链接全部面试题及答案PDF

1. 什么是线程?

线程是操作系统能够进⾏运算调度的最⼩单位,它被包含在进程之中,是进程中的实际运作单位,可以使⽤多线程对
进⾏运算提速。

⽐如,如果⼀个线程完成⼀个任务要100毫秒,那么⽤⼗个线程完成改任务只需10毫秒

2. 并行和并发有什么区别?

• 并行:多个处理器或多核处理器同时处理多个任务。

• 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。

3. 线程和进程的区别?

一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度。

4. 守护线程是什么?

守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。在 Java 中垃圾回收线程就是特殊的守护线程。

5. 什么是线程安全和线程不安全?

1 、线程安全
线程安全: 就是多线程访问时,采⽤了加锁机制,当⼀个线程访问该类的某个数据时,进⾏保护,其他线程不能进⾏ 访问,直到该线程读取完,其他线程才可使⽤。不会出现数据不⼀致或者数据污染。
Vector 是⽤同步⽅法来实现线程安全的, ⽽和它相似的ArrayList不是线程安全的。

2 、线程不安全
线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据 线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,⽽⽆写操作,⼀般来说,这个全局变量是线程安全的;若有多个
线程同时执⾏写操作,⼀般都需要考虑线程同步,否则的话就可能影响线程安全。

6. 创建线程有哪几种方式?

创建线程有三种方式:

• 继承 Thread 重写 run 方法;

• 实现 Runnable 接口;

• 实现 Callable 接口。

7. 说一下 runnable 和 callable 有什么区别?

runnable 没有返回值,callable 可以拿到有返回值,callable 可以看作是 runnable 的补充。

8. 线程有哪些状态?

线程的状态:

• NEW 尚未启动

• RUNNABLE 正在执行中

• BLOCKED 阻塞的(被同步锁或者IO锁阻塞)

• WAITING 永久等待状态

• TIMED_WAITING 等待指定的时间重新被唤醒的状态

• TERMINATED 执行完成

9. 什么是CAS?

1 、 CAS (compare and swap)的缩写,中⽂翻译成⽐较并交换。

2 、 CAS 不通过JVM,直接利⽤java本地⽅ JNI (Java Native Interface为JAVA本地调⽤) ,直接调⽤ CPU 的cmpxchg (是 汇编指令)指令。

3、利⽤CPU的CAS指令,同时借助JNI来完成Java的⾮阻塞算法,实现原⼦操作。其它原⼦操作都是利⽤类似的特性完成 的。

4 、整个java.util.concurrent都是建⽴在CAS之上的,因此对于synchronized阻塞算法, J.U.C在性能上有了很⼤的提升。

5 、 CAS是项乐观锁技术 ,当多个线程尝试使⽤CAS同时更新同⼀个变量时,只有其中⼀个线程能更新变量的值,⽽其它线程都失败,失败的线程并不会被挂起,⽽是被告知这次竞争中失败,并可以再次尝试。

使⽤CAS在线程冲突严重时,会⼤幅降低程序性能;CAS只适合于线程冲突较少的情况使⽤。  

synchronized在jdk1.6之后,已经改进优化。synchronized的底层实现主要依靠Lock-Free的队列,基本思路是⾃旋后阻塞,竞 争切换后继续竞争锁,稍微牺牲了公平性,但获得了⾼吞吐量。  在线程冲突较少的情况下,可以获得和CAS类似的性能;⽽线 程冲突严重的情况下,性能远⾼于CAS。  

10. sleep() 和 wait() 有什么区别?

• 类的不同:sleep() 来自 Thread,wait() 来自 Object。

• 释放锁:sleep() 不释放锁;wait() 释放锁。

• 用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。

11. notify()和 notifyAll()有什么区别?

notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。

12. 线程的 run() 和 start() 有什么区别?

start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。run() 可以重复调用,而 start() 只能调用一次。

13. 创建线程池有哪几种方式?

线程池创建有七种方式,最核心的是最后一种:

• newSingleThreadExecutor():它的特点在于工作线程数目被限制为 1,操作一个无界的工作队列,所以它保证了所有任务的都是被顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目;

• newCachedThreadPool():它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过 60 秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使用 SynchronousQueue 作为工作队列;

• newFixedThreadPool(int nThreads):重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有 nThreads 个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目 nThreads;

• newSingleThreadScheduledExecutor():创建单线程池,返回 ScheduledExecutorService,可以进行定时或周期性的工作调度;

• newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()类似,创建的是个 ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程;

• newWorkStealingPool(int parallelism):这是一个经常被人忽略的线程池,Java 8 才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序;

• ThreadPoolExecutor():是最原始的线程池创建,上面1-3创建方式都是对ThreadPoolExecutor的封装。

14. 什么是乐观锁和悲观锁?

1 、悲观锁

Java在JDK1.5之前都是靠synchronized关键字保证同步的,这种通过使⽤⼀致的锁定协议来协调对共享状态的访 问,可以确保⽆论哪个线程持有共享变量的锁,都采⽤独占的⽅式来访问这些变量 。独占锁其实就是⼀种悲观锁,所以 可以说synchronized是悲观锁。

2 、乐观锁

乐观锁( Optimistic Locking)其实是⼀种思想。相对悲观锁⽽⾔, 乐观锁假设认为数据⼀般情况下不会造成冲突, 所以在数据进⾏提交更新的时候,才会正式对数据的冲突与否进⾏检测 ,如果发现冲突了,则让返回⽤户错误的信息,
让⽤户决定如何去做。

memcached使⽤了cas乐观锁技术保证数据⼀致性。

15. 什么是Executors框架?

Java通过Executors提供四种线程池,分别为:

1 、 newCachedThreadPool创建⼀个可缓存线程池, 如果线程池⻓度超过处理需要,可灵活回收空闲线程,若⽆可 回收,则新建线程。

2 、 newFixedThreadPool 创建⼀个定⻓线程池, 可控制线程最⼤并发数,超出的线程会在队列中等待。

3 、 newScheduledThreadPool 创建⼀个定⻓线程池, ⽀持定时及周期性任务执⾏。

4 、 newSingleThreadExecutor 创建⼀个单线程化的线程池, 它只会⽤唯⼀的⼯作线程来执⾏任务,保证所有任务 按照指定顺序(FIFO, LIFO, 优先级)执⾏。

16. 什么是阻塞队列?如何使⽤阻塞队列来实现⽣产者-消费者模型?

1 、 JDK7提供了7个阻塞队列 。(也属于并发容器)

i. ArrayBlockingQueue :⼀个由数组结构组成的有界阻塞队列。

ii. LinkedBlockingQueue :⼀个由链表结构组成的有界阻塞队列。

iii. PriorityBlockingQueue :⼀个⽀持优先级排序的⽆界阻塞队列。

iv. DelayQueue:⼀个使⽤优先级队列实现的⽆界阻塞队列。

v. SynchronousQueue:⼀个不存储元素的阻塞队列。

vi. LinkedTransferQueue:⼀个由链表结构组成的⽆界阻塞队列。

vii. LinkedBlockingDeque:⼀个由链表结构组成的双向阻塞队列。

2、概念: 阻塞队列是⼀个在队列基础上⼜⽀持了两个附加操作的队列。

3 、 2个附加操作:
⽀持阻塞的插⼊⽅法:队列满时,队列会阻塞插⼊元素的线程,直到队列不满。

⽀持阻塞的移除⽅法:队列空时,获取元素的线程会等待队列变为⾮空。

17. 线程池都有哪些状态?

18. 线程池中 submit() 和 execute() 方法有什么区别?

19. 在 Java 程序中怎么保证多线程的运行安全?

20. 多线程中 synchronized 锁升级的原理是什么?

21. 什么是死锁?

22. 怎么防止死锁?

23. 什么是Callable和Future?

24. ThreadLocal 是什么?有哪些使用场景?

25. 说一下 synchronized 底层实现原理?

26. synchronized 和 volatile 的区别是什么?

27. synchronized 和 Lock 有什么区别?

28. synchronized 和 ReentrantLock 区别是什么?

29. 说一下 atomic 的原理?

30. 什么是多线程的上下⽂切换?

31. start()⽅法和run()⽅法的区别?

32. Runnable接⼝和Callable接⼝的区别?

33. volatile关键字的作⽤?

34. Java中如何获取到线程dump⽂件?

35. ⾼并发、任务执⾏时间短的业务怎样使⽤线程池?并发不⾼、任务执⾏时间⻓的业务怎样使⽤线程池?并发⾼、 业务执⾏时间⻓的业务怎样使⽤线程池?

36. 如果你提交任务时,线程池队列已满,这时会发⽣什么?

37. 锁的等级:⽅法锁、对象锁、类锁?

38. 如果同步块内的线程抛出异常会发⽣什么?

39. 并发编程(concurrency)并⾏编程(parallellism)有什么区别?

40. 如何保证多线程下 i++ 结果正确?

41. ⼀个线程如果出现了运⾏时异常会怎么样?

42. 如何在两个线程之间共享数据?

43. ⽣产者消费者模型的作⽤是什么?

44. 怎么唤醒⼀个阻塞的线程?

45. Java中⽤到的线程调度算法是什么

46. 单例模式的线程安全性?

47. 线程类的构造⽅法、静态块是被哪个线程调⽤的?

48. 同步⽅法和同步块,哪个是更好的选择?

49. 可以运⾏时kill掉⼀个线程吗?

50、线程a,b,c,d运⾏任务,怎么保证当a,b,c线程执⾏完再执⾏d线程?

51、⾼并发系统如何做性能优化?如何防⽌库存超卖?

下载链接博主已将以上这些面试题整理成了一个面试手册,是PDF版的

作者:蜗牛201
出处:https://www.cnblogs.com/woniu201/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
如果文中有什么错误,欢迎指出。以免更多的人被误导。

推荐这些文章:

Java面试题及答案2(最新版持续更新)

Java面试题及答案(2022版),适用于应届生、用工作经验的程序员,每道都是认真筛选出的高频面试题,助力大家能找到满意的工作!
下载链接:全部面试题及答案PDF
1.什么是B/S架构?什么是C/S架构
B/S(Browser/Server),浏览器/服务器程序;
C/S(Client/Server),客户端/服务端,桌面应用程序
2.Java都有那些开发平台?
JAVA SE :主要用在客户端开发
JAVA EE :主要用在web应用程序开发
JAVA ME :主要用在嵌入式应用程序开发
3.什么是JVM? java虚拟机包括什么?
JVM : java虚拟机,运用硬件或软件手段实现的虚拟...

2020年最新版,分享初中高级Java面试题合集附答案

Java面试前需要做足各方面的准备工作,大家肯定都会浏览大量的面试题过往的面试经验,本人也不例外,通过浏览面试题和以往的面试经历,总结了初级、中级、高级的面试题以及面试技巧和面试经验,供大家学习讨论。
面试题-基础篇
Java基础篇——Java开发面试题1期
Java基础篇——Java开发面试题2期
Java基础篇——Java开发面试题3期
Java基础篇——Java开发面试题4期
Java基础篇——Java开发面试题5期
Java基础篇——Java开发面试题6期
Java基础篇——Java开发面试题7期
Java基础篇——Java开发面试题8期
Java基础篇——Java中switch c...

最全多线程经典面试题和答案

Java实现线程有哪几种方式?
1、继承Thread类实现多线程2、实现Runnable接口方式实现多线程3、使用ExecutorService、Callable、Future实现有返回结果的多线程
多线程同步有哪几种方法?
Synchronized关键字,Lock锁实现,分布式锁等。
Runnable和Thread用哪个好?
Java不支持类的多重继承,但允许你实现多个接口。所以如果你要继承其他类,也为了减少类之间的耦合性,Runnable会更好。
Java中notify和notifyAll有什么区别?
notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地...

史上最强多线程面试44题和答案

1、并发编程三要素?
1)原子性
原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。
2)可见性
可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。
实现可见性的方法:
synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见性。
3)有序性
有序性,即程序的执行顺序按照代码的先后顺序来执行。
2、多线程的价值?
1)发挥多核CPU的优势
多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的,采用多线程的方式去同时完成...

Java多线程—线程通信

线程通信

涉及到三个方法:

wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器
notify():一旦执行此方法,就会唤醒wait的一个线程,如果有多个线程被wait,就唤醒优先级高的线程
notifyAll():一旦执行此方法,就唤醒所有的线程

说明:1、以上三个方法只能使用在同步方法或同步代码块中。

...

线程池为甚么要用阻塞队列

线程池为甚么要用阻塞队列

一般队列只能保证作为一个有线长度的缓冲区,如果超过了缓冲区长度,就无法保留当前任务了,阻塞队列通过阻塞可以保留当前想要继续入队的任务,阻塞队列可以保证任务队列中没有任务时阻塞队列获取任务的线程(即线程池中没有任务时,阻塞核心线程),使得线程进入wait状态,释放cpu
线程创建的时候,需要获取全局锁,这个时候其他的线程就需要阻塞,影响整体性能。

 
阻塞队列主要是:有限的队列长度,队列满了,可以阻塞保留当前任务;队列为空,阻塞线程,保持核心线程不退出。
线程池如何超时:queue.poll(timeOut),当线程在过期时间内没有从队列中拉到任务,...

文章标题:Java多线程面试题及答案(最新版)
文章链接:https://www.dianjilingqu.com/51574.html
本文章来源于网络,版权归原作者所有,如果本站文章侵犯了您的权益,请联系我们删除,联系邮箱:saisai#email.cn,感谢支持理解。
THE END
< <上一篇
下一篇>>