Java 中的锁有哪些种类?它们有什么区别?
时间: 2023-12-24 20:04:45 浏览: 36
Java 中的锁主要可以分为两类:内置锁和显式锁。
1. 内置锁
内置锁是 Java 中最基本的锁,它是通过 synchronized 关键字来实现的。内置锁可以用于方法或代码块上,当一个线程进入 synchronized 代码块时,它会自动地获取锁。如果其他线程尝试获取同一把锁,它们就会被阻塞,直到该锁被释放。内置锁的优点是使用简单,但是缺点是灵活性不够,例如无法对锁进行条件等待的控制。
2. 显式锁
与内置锁相比,显式锁提供了更多的灵活性和控制力,例如可重入性、公平性和超时等待。Java 中的显式锁主要包括 ReentrantLock、ReentrantReadWriteLock、StampedLock 等。显式锁的优点是灵活性高,可以根据需要设置不同的锁属性和锁控制,但是缺点是使用较为复杂,需要手动获取和释放锁,如果使用不当可能会导致死锁等问题。
3. 可重入锁
可重入锁是指同一个线程可以多次获得同一把锁,而不会导致死锁。Java 中的内置锁和 ReentrantLock 都是可重入锁。可重入锁的优点是方便使用,但是需要注意避免死锁问题。
4. 公平锁和非公平锁
公平锁是指多个线程按照请求的顺序获取锁,也就是说,先请求锁的线程先获取锁。非公平锁则没有这个限制,可能会导致某些线程一直获取不到锁。Java 中的 ReentrantLock 支持公平锁和非公平锁的模式。
5. 乐观锁和悲观锁
乐观锁和悲观锁是指处理并发访问时的两种不同思路。悲观锁认为并发访问是常态,因此总是假定会发生冲突,每次访问都会加锁,这种方式可以确保数据的一致性,但是加锁的代价较高。乐观锁则相反,它认为并发冲突的概率较小,因此不加锁,而是通过版本号等方式来检测并发冲突并解决。Java 中的 CAS(Compare and Swap)就是一种乐观锁的实现方式。