Java Lock 入门

在多线程编程中,正确地管理并发访问资源对于保证程序的正确性和效率至关重要。Java 提供了一种多样化的锁(Lock)机制来协助开发者实现线程同步和互斥控制。本文将深入探讨 Java 中的锁机制,涵盖基础概念、使用方法、常见实践和最佳实践,以帮助读者深入理解并高效使用 Java Lock。

目录

  1. 简介
  2. Java Lock 基础概念
  3. Java Lock 使用方法
  4. Java Lock 常见实践
  5. Java Lock 最佳实践
  6. 小结
  7. 参考资料

简介

锁用于管理对共享资源的访问,防止多个线程同时进入临界区(critical section)以避免数据争用(race condition)。Java 在 java.util.concurrent 包中提供了多种锁实现,用以替代传统的 synchronized 块,具备更灵活的锁定机制及更好的性能表现。

Java Lock 基础概念

Java 中的锁主要由 Lock 接口及其实现类构成。与 synchronized 相比,Lock 接口提供了更高级的锁定操作。常见的锁实现包括:

  • ReentrantLock: 可重入锁,具有与隐式监视器锁(synchronized)相同的基本行为和语义。

  • ReadWriteLock: 读写锁,允许多个读线程同时持有读锁,但写锁是独占的。

  • StampedLock: 一种乐观读的锁,实现锁的升级和降级操作,以提升高并发环境下的性能。

Java Lock 使用方法

使用 ReentrantLock

ReentrantLock 是最常用的锁之一,其使用非常简单。下面是一个基本示例:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final Lock lock = new ReentrantLock();private int counter = 0;public void increment() {lock.lock();try {counter++;} finally {lock.unlock();}}public int getCounter() {return counter;}
}

使用 ReadWriteLock

ReadWriteLock 提供了一个适合应对读多写少场景的锁:

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockExample {private final ReadWriteLock rwLock = new ReentrantReadWriteLock();private int counter = 0;public void increment() {rwLock.writeLock().lock();try {counter++;} finally {rwLock.writeLock().unlock();}}public int getCounter() {rwLock.readLock().lock();try {return counter;} finally {rwLock.readLock().unlock();}}
}

使用 StampedLock

StampedLock 提供了额外的优势,可以在高并发需求下提供更好的性能:

import java.util.concurrent.locks.StampedLock;public class StampedLockExample {private final StampedLock stampedLock = new StampedLock();private int counter = 0;public void increment() {long stamp = stampedLock.writeLock();try {counter++;} finally {stampedLock.unlockWrite(stamp);}}public int getCounter() {long stamp = stampedLock.tryOptimisticRead();int currentCounter = counter;if (!stampedLock.validate(stamp)) {stamp = stampedLock.readLock();try {currentCounter = counter;} finally {stampedLock.unlockRead(stamp);}}return currentCounter;}
}

Java Lock 常见实践

  1. 避免锁嵌套:锁嵌套容易导致死锁问题。必须避免在实现中使用多个锁持有顺序。

  2. 合理选择锁类型:根据场景选择合适的锁类型,例如在读多写少的场景中使用 ReadWriteLock

  3. 及时释放锁:务必在 finally 块中释放锁,保证程序异常情况下锁能被正确释放。

Java Lock 最佳实践

  • 使用 try-lock 进行超时控制:避免长时间获取不到锁而导致线程挂起,可以使用 tryLock(long timeout, TimeUnit unit) 方法。

  • 合适粒度的锁:锁的粒度过大会降低并行度,而过小又可能导致频繁的锁争用,需要在性能和安全性之间取得平衡。

  • 乐观读:在高并发环境中,可以通过 StampedLock 的乐观读来尽量减少写锁的使用。

小结

Java 的锁机制为多线程开发提供了丰富和灵活的同步策略。根据应用场景,合理选择和使用锁,可以有效提高应用的并行性和资源的利用效率。

参考资料

  1. Java Documentation - Lock Interface
  2. Java Concurrency in Practice - Brian Goetz
  3. Effective Java - Joshua Bloch

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/877462.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pdf处理--tts(待重写)

1.提取正文2.裁剪页眉 https://smallpdf.com/cn/crop-pdf#r=crop-pages3.拆分4.ocr 效果图--白描:效果图--4Videosoft PDF Converter Ultimate:5.阅读器与tts引擎 开源阅读:https://github.com/gedoor/legado tts-server-android:https://github.com/jing332/tts-server-an…

INFINI Labs 产品更新 | Console 发布 TopN 功能,Easysearch 新增 Rollup 能力等

INFINI Labs 产品全新发布!此次更新为大家带来了 Console 的全新 TopN 功能,让您能够更高效地定位最关键的节点或索引;Easysearch 新增 Rollup 能力,大幅提升监控指标的存储周期并优化分析体验;此外,Framework 还修复了多项缺陷并进行了多处优化。欢迎下载体验,探索更多…

03-一个例子

登录被测系统bysms双击运行runserver.bat 访问页面:http://127.0.0.1/mgr/sign.html 账号:byhy,密码:88888888 可以直接在pycharm的Terminal中运行hytest,不需要打开命令行窗口 浏览器驱动的打印信息: 禁止 chromedriver 日志写屏1 from selenium import webdriver 2 3 …

blog tips

markdown 内嵌 html 使图片并排点击查看代码 <div style="display: flex; gap: 10px; justify-content: space-between;"><img src="图片1地址" style="width: 49%; height: auto;"/><img src="图片2地址" style="…

【数学】已知正方形相邻两点坐标求另外两点坐标

已知正方形相邻两点(a,b)与(c,d)坐标公式: \( (x_3,y_3) = (c + (b-d), d - (a-c)) \\ (x_4,y_4) = (a + (b-d), b - (a-c)) \\ (x_5,y_5) = (a - (b-d), b + (a-c)) \\ (x_6,y_6) = (c - (b-d), d + (a-c)) \)

25.1.31小记

多态类型声明类型 : 定义时候的类型 动态类型 : 运行到那里的时候对应的具体类型 向上造型(cast) : 将子类类型的对象赋给父类的变量 (不能将一个父类的变量赋予一个子类的变量) 赋值运算符 : 将管理者管理的对象进行改变(改变的是指针)其中造型(cast)的意义是将某…

MacOS修改应用快捷键的一般思路

具体步骤为:使用CheatSheet软件查看菜单项名称 在系统设置中修改菜单项的快捷键举个例子:修改Chrome中左右切换tab的快捷键(系统语言为英文,中文同理) 默认采用Ccontrol Tab和Control + Shift + Tab(或Command Shift [和Command Shift ])可以左右切换tab。 现在希望将其…

UE4.27, 模块实践, Slate的UI开发 (一)

1. 基本概念1.1. Slate是虚幻UI框架设计的底层,该框架中最基本的类是SWidget1.1.1.显然,我们容易注意到,直属于该框架的类拥有着指定的命名规则,即以S开头1.2. UMG, UWidget, Slate关联1.2.1. UMG:Unreal Motion Graphics UI Designer 虚幻的图形界面设计工具1.2.2. 单纯Sl…

Brainfly: 用 C# 类型系统构建 Brainfuck 编译器

Brainfly: 用 C# 类型系统构建 Brainfuck 编译器Brainfuck 简介 Brainfuck 是由 Urban Mller 在 1993 年创造的一门非常精简的图灵完备的编程语言。 正所谓大道至简,这门编程语言简单到语法只有 8 个字符,每一个字符对应一个指令,用 C 语言来描述的话就是:字符 含义> ++…

01-hytest简介

参考教程:http://vip3.byhy.net/auto/pyatframework/hytest-01/ 安装:pip3 install hytest hytest对应的python版本要求:Python3.6或者更高版本 运行hytest自动化测试:打开命令行窗口 切换到自动化代码根目录 运行hytest,运行hytest其实就是运行python -m hytest.run 如果…

【编码】自定义通信协议——实现零拷贝文件传输

前言 上一篇随笔,介绍了如何扩展自定义协议的请求类型。本篇随笔我将介绍如何基于这个自定义协议来实现文件传输,其中将涉及数据分片和零拷贝 在设计自定义协议之前,我们首先了解一下HTTP协议是如何处理文件传输的。 HTTP协议的实现方式 在这里,我们主要讨论应用最广泛的HT…

研发的护城河到底是什么?

0 你的问题,我知道! 和大厂朋友聊天,他感叹原来努力干活,做靠谱研发,积累职场经验,干下来,职业发展一般问题不大。而如今大厂“年轻化”,靠谱再不能为自己续航,企业似乎也不愿意持续为经验买单。 在这不确定时代,职业发展中有无硬通货? 更长远职业发展角度:要抓住机…