130道 Java多线程面试题汇总

我把所有Java相关的面试题和答案都整理成了PDF,并且带书签目录,阅读起来非常方便

面试题及答案PDF下载https://www.hicxy.com/2645.html

面试题及答案PDF下载https://www.hicxy.com/2645.html

面试题及答案PDF下载https://www.hicxy.com/2645.html

1. Runnable接口和Callable接口的区别

有点深的问题了,也看出一个Java程序员学习知识的广度。

1、 Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;

2、 Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。

这其实是很有用的一个特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。

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

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。

  • void notify(): 唤醒一个正在等待该对象的线程。
  • void notifyAll(): 唤醒所有正在等待该对象的线程。

notify可能会导致死锁,而notifyAll则不会

任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码

使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。

wait() 应配合while循环使用,不应使用if,务必在wait()调用前后都检查条件,如果不满足,必须调用notify()唤醒另外的线程来处理,自己继续wait()直至条件满足再往下执行。

notify() 是对notifyAll()的一个优化,但它有很精确的应用场景,并且要求正确使用。不然可能导致死锁。正确的场景应该是 WaitSet中等待的是相同的条件,唤醒任一个都能正确处理接下来的事项,如果唤醒的线程无法正确处理,务必确保继续notify()下一个线程,并且自身需要重新回到WaitSet中.

3. 什么是竞态条件?你怎样发现和解决竞争?

当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。

在临界区中使用适当的同步就可以避免竞态条件。

界区实现方法有两种,一种是用synchronized,一种是用Lock显式锁实现。

4. 什么是Daemon线程?它有什么意义?

所谓后台(daemon)线程,是指在程序运行的时候在后台提供一种通用服务的线程,并且这个线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程。

反过来说, 只要有任何非后台线程还在运行,程序就不会终止。必须在线程启动之前调用setDaemon()方法,才能把它设置为后台线程。注意:后台进程在不执行finally子句的情况下就会终止其run()方法。

比如:JVM的垃圾回收线程就是Daemon线程,Finalizer也是守护线程。

5. Executor框架的主要成员

ThreadPoolExecutor :可以通过工厂类Executors来创建。

可以创建3种类型的ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool、CachedThreadPool。

ScheduledThreadPoolExecutor :可以通过工厂类Executors来创建。

可以创建2中类型的ScheduledThreadPoolExecutor:ScheduledThreadPoolExecutor、SingleThreadScheduledExecutor

Future接口:Future和实现Future接口的FutureTask类来表示异步计算的结果。

Runnable和Callable:它们的接口实现类都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行。Runnable不能返回结果,Callable可以返回结果。

后面的问题,大家可以先自己独立思考一下。

另外我把所有Java相关的面试题和答案都整理出来了,给大家参考一下

面试题及答案PDF下载https://www.hicxy.com/2645.html

面试题及答案PDF下载https://www.hicxy.com/2645.html

面试题及答案PDF下载https://www.hicxy.com/2645.html

6. ThreadLocal是什么

7. 向线程池提交任务

8. 为什么Thread类的sleep()和yield ()方法是静态的?

9. 什么是线程池?为什么要使用它?

10. # 1、同步普通方法

11. 如何避免死锁和检测

12. synchronized和ReentrantLock的区别

13. join方法实现原理

14. 举例说明同步和异步。

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

16. 什么是可重入锁(ReentrantLock)?

17. start()方法和run()方法的区别

18. Java中interrupted 和isInterruptedd方法的区别?

19. 当一个线程进入某个对象的一个synchronized的实例方法后,其它线程是否可进入此对象的其它方法?

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

21. volatile 变量和 atomic 变量有什么不同?

22. 为什么使用Executor框架比使用应用创建和管理线程好?

23. Java中活锁和死锁有什么区别?

24. 如何控制某个方法允许并发访问线程的大小?

25. 什么是自旋

26.

27. 在java中守护线程和本地线程区别?

28. 线程有哪些基本状态?

29. 什么是 FutureTask

30. ThreadLocal有什么用

31. 如何创建线程池

32. 说说自己是怎么使用 synchronized 关键字,在项目中用到了吗synchronized关键字最主要的三种使用方式:

33. 乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

34. 创建线程池参数有哪些,作用?

35. 什么是阻塞(Blocking)和非阻塞(Non-Blocking)?

36. 同步方法和同步块,哪个是更好的选择

37. Java Concurrency API中的Lock接口(Lock interface)是什么?对比同步它有什么优势?

38. 为什么代码会重排序?

39. Java中的死锁

40. 什么是多线程中的上下文切换?

41. # 3、同步类

42. 如何创建守护线程?以及在什么场合来使用它?

43. join与start调用顺序问题

44. Java中你怎样唤醒一个阻塞的线程?

45. 线程的sleep()方法和yield()方法有什么区别?

46. 线程类的构造方法、静态块是被哪个线程调用的

47. 多线程和单线程的区别和联系?

48. 线程同步和互斥有几种实现方法,都是什么?

49. Java中的同步集合与并发集合有什么区别?

50. 线程中断是否能直接调用stop,为什么?

51. 如何合理的设置线程池

52. synchronized包括哪两个jvm重要的指令?

53. 一个线程运行时发生异常会怎样?

54. 在多线程中,什么是上下文切换(context-switching)?

55. CopyOnWriteArrayList可以用于什么应用场景?

56. 什么是线程安全

57. 什么是ThreadLocal变量?

58. 什么是Executors框架?

59. 为什么wait, notify 和 notifyAll这些方法不在thread类里面?

60. 如何停止一个正在运行的线程

61. 什么是并发容器的实现?

62. 什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?

63. 线程池作用

64. sleep方法和wait方法有什么区别

65. Java中原子操作更新字段类,Atomic包提供了哪几个类?

66. 什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

67. 现在有 T1、T2、T3 三个线程,你怎样保证 T2 在 T1 执行完后执行,T3 在 T2 执行完后执 行?

68. 什么是Java内存模型

69. 为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用

70. 如何让正在运行的线程暂停一段时间?

71. 什么是线程安全?

72. SynchronizedMap和ConcurrentHashMap有什么区别?

73. 你如何确保main()方法所在的线程是Java 程序最后结束的线程?

74. 你如何在Java中获取线程堆栈?

75. volatile关键字的作用

76. 什么是 Callable 和 Future?

77. 如何确保线程安全?

78. 为什么wait(), notify()和notifyAll ()必须在同步方法或者同步块中被调用?

79. Java中interrupted 和 isInterrupted方法的区别?

80. 什么是Java Timer 类?如何创建一个有特定时间间隔的任务?

81. 自旋锁的优缺点?

82. synchronized锁的是什么?

83. 什么是线程池? 为什么要使用它?

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

85. Thread类中的yield方法有什么作用?

86. ThreadLocal原理,使用注意点,应用场景有哪些?

87. 常用的线程池模式以及不同线程池的使用场景?

88. 线程的创建方式

89. # 2、同步静态方法

90. wait 和 sleep 方法的不同?

91. 不使用stop停止线程?

92. 一个线程如果出现了运行时异常会怎么样

93. 在Java中Executor、ExecutorService、Executors的区别?

94. Thread.sleep(0)的作用是什么

95. 死锁与活锁的区别,死锁与饥饿的区别?

96. 线程安全的级别

97. 高并发、任务执行时间短的业务怎样使用线程池?并发不高、任务执行时间长的业务怎样使用线程池?并发高、业务执行时间长的业务怎样使用线程池?

98. # 5、同步对象实例

99. Java中Semaphore是什么?

100. 线程的状态转换?

101. 线程池工作流程

102. 什么是不可变对象,它对写并发应用有什么帮助?

103. join方法传参和不传参的区别?

104. 为什么wait和notify方法要在同步块中调用?

105. 什么是原子操作?在Java Concurrency API中有哪些原子类(atomic classes)?

106. 在Java中CycliBarriar和CountdownLatch有什么区别?

107. Java中堆和栈有什么不同?

108. volatile 是什么?可以保证有序性吗?

109. 多线程有什么用?

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

111. 你对线程优先级的理解是什么?

112. 讲一下 synchronized 关键字的底层原理

113. ConcurrentHashMap的并发度是什么

114. 为什么使用Executor框架?

115. 简述线程、程序、进程的基本概念。以及他们之间关系是什么?

116. join方法的作用?

117. 说一说自己对于 synchronized 关键字的了解

118. 在线程中你怎么处理不可控制异常?

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

120. 怎么检测一个线程是否拥有锁?

121. Java中如何获取到线程dump文件

122. 什么是阻塞式方法?

123. 线程的状态

124. Java中notify 和 notifyAll有什么区别?

125. wait()方法和notify()/notifyAll()方法在放弃对象监视器时有什么区别

126. 关闭线程池

127. 为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?

128. 用户线程和守护线程有什么区别?

129. 请说出与线程同步以及线程调度相关的方法。

130. Synchronized 有几种用法?

131. Java中用到的线程调度算法是什么?

132. # 4、同步this实例

原文地址:https://www.cnblogs.com/wyl-0120/p/15456674.html