面试题答案
一键面试-
使用
synchronized
关键字- 原理:
synchronized
关键字可以用来修饰方法或者代码块。当一个线程进入被synchronized
修饰的方法或代码块时,它会自动获取对象的锁(对于静态方法,获取的是类的锁)。其他线程如果也想进入该同步区域,必须等待锁的释放。这样就保证了同一时间只有一个线程能访问共享资源,从而实现线程安全。 - 适用场景:适用于对共享资源的访问频率较高,且同步代码块或方法执行时间相对较短的场景。例如在一个简单的计数器类中,对计数器变量的增减操作可以使用
synchronized
修饰方法来保证线程安全。
- 原理:
-
使用
ReentrantLock
- 原理:
ReentrantLock
是Java 5.0引入的一个可重入的互斥锁,它提供了比synchronized
更灵活的锁控制。ReentrantLock
通过内部的AQS(AbstractQueuedSynchronizer)框架来实现线程的排队等待和锁的分配。线程获取锁时调用lock()
方法,释放锁时调用unlock()
方法,使用tryLock()
方法可以尝试获取锁而不阻塞。 - 适用场景:适用于需要更细粒度控制锁的获取和释放,以及需要实现公平锁(按照线程等待的先后顺序获取锁)的场景。比如在复杂的并发数据结构实现中,需要精确控制锁的获取和释放时机时,可以使用
ReentrantLock
。
- 原理:
-
使用
ThreadLocal
- 原理:
ThreadLocal
为每个线程提供一个独立的变量副本,每个线程访问自己的副本,不会相互干扰,从而避免了线程安全问题。当一个线程调用ThreadLocal
的get()
方法时,它会获取到属于自己的变量副本;调用set()
方法时,也是对自己的副本进行操作。 - 适用场景:适用于每个线程需要有自己独立的上下文数据,且数据与线程生命周期相关的场景。例如在数据库连接管理中,每个线程需要维护自己的数据库连接,就可以使用
ThreadLocal
来管理数据库连接对象。
- 原理: