Java中的几种锁
【摘要】 Java中的锁机制是并发编程中用来确保多个线程在访问共享资源时不发生数据竞争的关键工具。Java提供了多种锁机制来帮助开发者管理线程同步,以下是Java中常见的几种锁: 1. 乐观锁与悲观锁乐观锁:乐观锁是一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低。读数据时认为别的线程不会正在进行修改(所以没有上锁),写数据时判断当前值与期望值是否相同,如果相同则进行更新(更新期间加锁,保...
Java中的锁机制是并发编程中用来确保多个线程在访问共享资源时不发生数据竞争的关键工具。Java提供了多种锁机制来帮助开发者管理线程同步,以下是Java中常见的几种锁:
1. 乐观锁与悲观锁
- 乐观锁:乐观锁是一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低。读数据时认为别的线程不会正在进行修改(所以没有上锁),写数据时判断当前值与期望值是否相同,如果相同则进行更新(更新期间加锁,保证是原子性的)。Java中的乐观锁通常通过CAS(Compare And Swap/Set)操作实现。
- 悲观锁:悲观锁是一种悲观思想,即认为写多读少,遇到并发写的可能性高,每次读写数据时都会上锁。其他线程想要读写这个数据时,会被阻塞,直到持有锁的线程释放锁。Java中的synchronized关键字和ReentrantLock都是悲观锁的实现。
2. 自旋锁
- 简介:自旋锁是一种技术,用于让线程等待时不进行线程切换,而是执行一个忙循环(自旋)。如果物理机器有多个处理器核心,可以让后面请求锁的那个线程稍等一会,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。
- 优点:避免了线程切换的开销。
- 缺点:如果自旋时间过长,会消耗处理器资源,带来性能的浪费。因此自旋锁通常有一个自旋次数的限制,超过限制仍未获取到锁,则使用传统方式挂起线程。
3. 可重入锁(递归锁)
- 简介:可重入锁是一种技术,允许同一个线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞。Java中的ReentrantLock和synchronized修饰的方法或代码段都是可重入锁的实现。
- 作用:避免死锁。如果一个线程已经持有某把锁,再次申请该锁时,如果是可重入锁,则能够成功获取,避免死锁的发生。
4. 读写锁
- 简介:读写锁是一种技术,通过ReentrantReadWriteLock类来实现。为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁。读锁允许多个线程同时获取,写锁则只允许一个线程获取。
- 读锁:允许多个线程同时读取共享资源。
- 写锁:在一个线程写数据时,不允许其他线程读或写。
5. 公平锁与非公平锁
- 公平锁:公平锁是一种策略,多个线程按照申请锁的顺序来获取锁。在并发环境中,每个线程会先查看此锁维护的等待队列,如果当前等待队列为空,则占有锁;如果等待队列不为空,则加入到等待队列的末尾,按照FIFO的原则从队列中拿到线程,然后占有锁。
- 非公平锁:非公平锁则不保证线程按照申请锁的顺序来获取锁。线程尝试获取锁时,如果获取不到,则再采用公平锁的方式。非公平锁的性能通常高于公平锁,但有可能造成线程饥饿(某个线程很长一段时间获取不到锁)。Java中的synchronized是非公平锁,ReentrantLock默认也是非公平锁,但可以通过构造函数指定为公平锁。
6. 独占锁与共享锁
- 独占锁:独占锁是一种策略,只能有一个线程获取锁,以独占的方式持有锁。Java中的synchronized和ReentrantLock的写锁都是独占锁的实现。
- 共享锁:共享锁允许多个线程获取锁,以共享的方式持有锁。Java中的ReentrantReadWriteLock的读锁就是共享锁的实现。
7. 重量级锁、轻量级锁与偏向锁
- 重量级锁:重量级锁是synchronized关键字在JDK 6之前的实现方式,通过对象内部的监视器锁(monitor)来实现,监视器锁本身依赖底层的操作系统的Mutex Lock来实现。重量级锁的开销较大,适合小规模的同步需求。
- 轻量级锁:JDK 6为了减少获得锁和释放锁所带来的性能消耗,引入了轻量级锁。轻量级锁是一种优化手段,当线程竞争不激烈时,使用轻量级锁可以减少系统开销。
- 偏向锁:偏向锁是JDK 6引入的另一种优化手段。它是指一段同步代码一直被一个线程所访问时,该线程会自动获取锁,减少锁的竞争。偏向锁是一种乐观锁,假设大多数情况下锁不会被其他线程竞争。
8. 其他锁
- 分段锁:分段锁不是一种实际存在的锁,而是一种锁的设计思想。它通过将对象分成多个段,每个段都有自己的锁,来实现更细粒度的锁控制。concurrentHashMap就采用了分段锁的思想。
- StampedLock:StampedLock是ReadWriteLock的一个变体,它引入了一个“戳”的概念来支持乐观读锁。乐观读锁不会阻塞写操作,但在读操作期间如果发生了写操作,乐观读锁会自动失效。
总之,Java中的锁机制多种多样,每种锁都有其特定的应用场景和优缺点。开发者在选择锁时,需要根据具体的应用场景和需求来选择合适的锁机制。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)