11. 什么是线程间通信?如何实现线程间通信?
答案:
线程间通信是指多个线程之间通过共享内存或消息传递的方式来传递信息的过程。在Java中,可以通过以下方式实现线程间通信:
- 共享内存:使用共享变量(如
volatile
、synchronized
)来实现线程间数据共享。 - 管程(Monitor):使用
wait()
、notify()
和notifyAll()
方法来实现线程的等待和唤醒。 - 阻塞队列:使用
BlockingQueue
等并发集合类来实现线程安全的消息传递。
12. 什么是ThreadLocal?它有什么作用?
答案:
ThreadLocal是Java中的一个类,用于在多线程环境下存储线程私有的变量。每个线程都有自己独立的ThreadLocal变量副本,互不干扰。ThreadLocal通常用于解决线程安全问题,例如在每个线程中保持一个对象的副本,而不是通过参数传递。
13. 什么是Java中的锁?有哪些类型的锁?
答案:
锁是用于控制多个线程访问共享资源的机制。在Java中,常见的锁包括:
- 内置锁(Intrinsic Lock):即
synchronized
关键字提供的锁机制。 - 重入锁(Reentrant Lock):
ReentrantLock
类提供的灵活的锁机制,支持公平锁和非公平锁。 - 读写锁(ReadWriteLock):
ReadWriteLock
接口及其实现类ReentrantReadWriteLock
,允许多个线程同时读取共享资源,但只有一个线程能够写入共享资源。
14. 什么是线程安全的集合?举例说明。
答案:
线程安全的集合是在多线程环境下使用的数据结构,它通过内部同步机制来确保对集合的操作是线程安全的。例如:
ConcurrentHashMap
:线程安全的哈希表实现。CopyOnWriteArrayList
:线程安全的动态数组实现,适合读多写少的场景。ConcurrentLinkedQueue
:线程安全的无界队列实现。
15. 什么是原子操作?Java中如何实现原子操作?
答案:
原子操作是指不可中断的一个或一系列操作,要么全部执行成功,要么全部不执行,没有中间状态。在Java中,可以通过以下方式实现原子操作:
- 使用
Atomic
包中的原子类,如AtomicInteger
、AtomicLong
等。 - 使用
volatile
关键字修饰的变量,保证可见性和禁止指令重排序。
16. Java中的CAS操作是什么?它有什么优缺点?
答案:
CAS(Compare And Swap)是一种乐观锁技术,用于实现多线程环境下的原子操作。它通过比较当前值与期望值是否相等来确定是否执行更新操作。优点是避免了使用锁带来的性能开销,缺点是可能存在ABA问题(解决方法是使用版本号等方式)和自旋操作可能造成CPU资源浪费。
17. 什么是并发集合?举例说明一个并发集合的使用场景。
答案:
并发集合是一种特殊的数据结构,支持并发访问和修改操作,适用于多线程环境。例如,ConcurrentHashMap
用于在多线程环境中安全地管理键值对,适合高并发的数据访问场景,如缓存管理、高并发计数器等。
18. 什么是线程池中的核心线程和最大线程数?
答案:
线程池中的核心线程是线程池中始终保持活动的线程数量,即使它们处于空闲状态。最大线程数是线程池中允许的最大线程数量,包括核心线程和非核心线程。当任务队列满时,线程池可以创建多达最大线程数的线程来处理任务。
19. 什么是线程池中的任务队列?它有哪些常见的类型?
答案:
线程池中的任务队列是用于存储待执行任务的缓冲区,常见的类型包括:
- 无界队列:如
LinkedBlockingQueue
,可以无限制地添加任务,直到内存耗尽。 - 有界队列:如
ArrayBlockingQueue
,限制了队列的最大容量,超出容量时会拒绝任务。 - 优先级队列:如
PriorityBlockingQueue
,根据任务的优先级顺序执行。
20. Java中如何创建一个线程?举例说明多种创建线程的方式。
答案:
在Java中,可以通过以下几种方式创建线程:
- 继承
Thread
类并重写run()
方法。 - 实现
Runnable
接口并将其传递给Thread
类的构造函数。 - 使用
Callable
和Future
接口创建可返回结果的线程。 - 使用线程池中的工厂方法创建线程,如
ExecutorService
的newThread()
方法。