Java 线程安全 ReentrantLock
在学习 Java 语言的过程中,多线程是一个算是进阶的选择。我最近又学到了一个新技能ReentrantLock
类,这个应该目前最简单的线程安全使用方式了,当然暴力synchronized
除外。
首先回顾一下之前的线程安全常用同步类的文章:
下面介绍一下ReentrantLock
类,看名字就是一个可重入锁,这个概念跟synchronized
中有点类似。我理解为这是一个简单易上手的线程安全操作类,不需要理解synchronized
带来的语法,不需要其他线程同步类锁需要的对各类 API 功能记忆。ReentrantLock
真的是一个非常好用的多线程安全工具类。
ReentrantLock
核心(个人看法)有两个方法lock()
和unlock()
,顾名思义,一个是加锁一个是释放锁,所有线程安全的操作可以写在这两个方法之间。这一点跟之前的文章如何mock固定QPS的接口、moco固定QPS接口升级补偿机制中用到的线程安全之流量控制类java.util.concurrent.Semaphore
的使用基本一致,相比之下java.util.concurrent.locks.ReentrantLock
相当于new java.util.concurrent.Semaphore((1, true)
。java.util.concurrent
这个包简直就是一个宝藏,欢迎有兴趣学习的童鞋翻一翻源码,其乐无穷。
下面演示一下ReentrantLock
的基本使用,中间用到了- Java自定义异步功能实践、利用守护线程隐式关闭线程池中用到的异步关键字,有兴趣的可以翻一翻,就是关键字fun
后面的代码块会有单独线程执行,这里用Java
语言进行演示。
控制台输出如下:
我觉得这两个 API 使用基本满足了常见的多线程编程需求了,唯一需要注意的就是unlock()
方法可能因为程序异常不会被执行,所以一般都放在finally
代码块中。
下面介绍几个非常用的 API,有助于解决非常见的需求:
获取锁,但是有超时时间,会返回是否加锁成功。
获取等待队列长度,这个不准,因为队列可能会发生变化:
判断是否上锁,这个和上面tryLocal
功能上有点重复:
还有一个标准较不常用的,获取当前线程持有锁的次数,这个牵扯到ReentrantLock
重入锁机制,就是一个线程可以持有很多次,但是只要次数不为零,其他线程都无法加锁成功,平时使用不多,没有谁单线程持有 N 多次锁:
Have Fun ~ Tester !
版权声明: 本文为 InfoQ 作者【FunTester】的原创文章。
原文链接:【http://xie.infoq.cn/article/5d47b654e4c3a80b8f3fc1e59】。文章转载请联系作者。
评论