Lock的使用

前言:本系列将从零开始讲解java多线程相关的技术,内容参考于《java多线程核心技术》与《java并发编程实战》等相关资料,希望站在巨人的肩膀上,再通过我的理解能让知识更加简单易懂。

目录

ReentrantLocak特性(对比synchronized)

尝试获得锁

获取到锁的线程能够响应中断

ReentrantLock(重入锁)

public class MyService {

private Lock lock = new ReentrantLock();

public void testMethod() {

lock.lock();

for (int i = 0; i < 5; i++) {

System.out.println("ThreadName=" + Thread.currentThread().getName()

+ (" " + (i + 1)));

}

lock.unlock();

}

}

效果和synchronized一样,都可以同步执行,lock方法获得锁,unlock方法释放锁

await方法

public class MyService {

private Lock lock = new ReentrantLock();

private Condition condition=lock.newCondition();

public void testMethod() {

try {

lock.lock();

System.out.println("开始wait");

condition.await();

for (int i = 0; i < 5; i++) {

System.out.println("ThreadName=" + Thread.currentThread().getName()

+ (" " + (i + 1)));

}

} catch (InterruptedException e) {

// TODO 自动生成的 catch 块

e.printStackTrace();

}

finally

{

lock.unlock();

}

}

}

通过创建Condition对象来使线程wait,必须先执行lock.lock方法获得锁

signal方法

public void signal()

{

try

{

lock.lock();

condition.signal();

}

finally

{

lock.unlock();

}

}

condition对象的signal方法可以唤醒wait线程

创建多个condition对象

一个condition对象的signal(signalAll)方法和该对象的await方法是一一对应的,也就是一个condition对象的signal(signalAll)方法不能唤醒其他condition对象的await方法

ReentrantLock类可以唤醒指定条件的线程,而object的唤醒是随机的

Condition类和Object类

Condition类的awiat方法和Object类的wait方法等效

Condition类的signal方法和Object类的notify方法等效

Condition类的signalAll方法和Object类的notifyAll方法等效

Lock的公平锁和非公平锁

Lock lock=new ReentrantLock(true);//公平锁

Lock lock=new ReentrantLock(false);//非公平锁

公平锁指的是线程获取锁的顺序是按照加锁顺序来的,而非公平锁指的是抢锁机制,先lock的线程不一定先获得锁。

ReentrantLock类的方法

getHoldCount() 查询当前线程保持此锁的次数,也就是执行此线程执行lock方法的次数

getQueueLength()返回正等待获取此锁的线程估计数,比如启动10个线程,1个线程获得锁,此时返回的是9

getWaitQueueLength(Condition condition)返回等待与此锁相关的给定条件的线程估计数。比如10个线程,用同一个condition对象,并且此时这10个线程都执行了condition对象的await方法,那么此时执行此方法返回10

hasWaiters(Condition condition)查询是否有线程等待与此锁有关的给定条件(condition),对于指定contidion对象,有多少线程执行了condition.await方法

hasQueuedThread(Thread thread)查询给定线程是否等待获取此锁

hasQueuedThreads()是否有线程等待此锁

isFair()该锁是否公平锁

isHeldByCurrentThread() 当前线程是否保持锁锁定,线程的执行lock方法的前后分别是false和true

isLock()此锁是否有任意线程占用

lockInterruptibly()如果当前线程未被中断,获取锁

tryLock()尝试获得锁,仅在调用时锁未被线程占用,获得锁

tryLock(long timeout TimeUnit unit)如果锁在给定等待时间内没有被另一个线程保持,则获取该锁

tryLock和lock和lockInterruptibly的区别

tryLock能获得锁就返回true,不能就立即返回false,tryLock(long timeout,TimeUnit unit),可以增加时间限制,如果超过该时间段还没获得锁,返回false

lock能获得锁就返回true,不能的话一直等待获得锁

lock和lockInterruptibly,如果两个线程分别执行这两个方法,但此时中断这两个线程,前者不会抛出异常,而后者会抛出异常

读写锁

ReentrantLock是完全互斥排他的,这样其实效率是不高的。

public void read() {

try {

try {

lock.readLock().lock();

System.out.println("获得读锁" + Thread.currentThread().getName()

+ " " + System.currentTimeMillis());

Thread.sleep(10000);

} finally {

lock.readLock().unlock();

}

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

读锁,此时多个线程可以或得读锁

public void write() {

try {

try {

lock.writeLock().lock();

System.out.println("获得写锁" + Thread.currentThread().getName()

+ " " + System.currentTimeMillis());

Thread.sleep(10000);

} finally {

lock.writeLock().unlock();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

写锁,此时只有一个线程能获得写锁

public void read() {

try {

try {

lock.readLock().lock();

System.out.println("获得读锁" + Thread.currentThread().getName()

+ " " + System.currentTimeMillis());

Thread.sleep(10000);

} finally {

lock.readLock().unlock();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public void write() {

try {

try {

lock.writeLock().lock();

System.out.println("获得写锁" + Thread.currentThread().getName()

+ " " + System.currentTimeMillis());

Thread.sleep(10000);

} finally {

lock.writeLock().unlock();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

结果是读锁释放后才执行写锁的方法,说明读锁和写锁是互斥的

总结

Lock类也可以实现线程同步,而Lock获得锁需要执行lock方法,释放锁需要执行unLock方法

Lock类可以创建Condition对象,Condition对象用来是线程等待和唤醒线程,需要注意的是Condition对象的唤醒的是用同一个Condition执行await方法的线程,所以也就可以实现唤醒指定类的线程

Lock类分公平锁和不公平锁,公平锁是按照加锁顺序来的,非公平锁是不按顺序的,也就是说先执行lock方法的锁不一定先获得锁

Lock类有读锁和写锁,读读共享,写写互斥,读写互斥

我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

java中多线程reentlock_java多线程系列(四)---ReentrantLock的使用相关推荐

  1. java 中lock,java中lock获取锁的四种方法

    在java接口中会存放着许多方法,方便线程使用时的直接调用.对于lock接口大家都不陌生,我们已经初步对概念进行了理解.那么在获取锁的方法上想必还不是很清楚.下面我们就lock获取锁的四种方法分别进行 ...

  2. java将一个整数按字节输出_在java中的整数类型有四种,分别是 byte  short int long 其中byte只有一个字节 0或1,在此不详细讲解。其他的三种类型如下:1、...

    在java中的整数类型有四种,分别是 byte  short int long 其中byte只有一个字节 0或1,在此不详细讲解. 其他的三种类型如下: 1. 基本类型:short 二进制位数:16 ...

  3. Java中的集合多线程的理解

    Java中的集合 1.List.Set和Queue [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DwpgIu9t-1587300088779)(file:///C:\ ...

  4. java中smb启动多线程_Java中SMB的相关应用

    SMB 服务操作 Ⅰ SMB简介 ​ SMB(全称是Server Message Block)是一个协议名,它能被用于Web连接和客户端与服务器之间的信息沟通.SMB协议作为一种局域网文件共享传输协议 ...

  5. java中你知道的这四种代码块吗?

    点击上方蓝字关注我们 大家好,我是雄雄,今天给大家分享的是:java中的四种代码块 什么叫代码块? 代码块就是将多行代码封装到一个"{}"中,形成一个独立的代码区,这就构成了代码块 ...

  6. java中判断undefined_Java虚拟机系列一:一文搞懂 JVM 架构和运行时数据区

    前言 之前写博客一直比较随性,主题也很随意,就是想到什么写什么,对什么感兴趣就写什么.虽然写起来无拘无束,自在随意,但也带来了一些问题,每次写完一篇后就要去纠结下一篇到底写什么,看来选择太多也不是好事 ...

  7. java中多线程reentlock_Java多线程系列——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为"独占锁". ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychr ...

  8. java多线程系列(四)---ReentrantLock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  9. java中HashMap在多线程环境下引起CPU100%的问题解决

    最近项目中出现了Tomcat占用CPU100%的情况,原以为是代码中出现死循环,后台使用jstack做了dump,发现是系统中不合理使用HashMap导致出现了死循环(注意不是死锁). 产生这个死循环 ...

最新文章

  1. 机器人十大前沿热点领域(2012-2022年)
  2. Poj 1112 Team Them Up!
  3. windows上安装gcc/g++环境(MinGW,msys64等)
  4. 【Python】学习笔记7-异常处理try。。except .. as e ....else
  5. python基础(part5)--容器类型之字符串
  6. c++虚函数的前奏--函数指针与回调
  7. CSS 再学习,基础篇
  8. Windows系统cmd命令检测dll文件
  9. Android开发笔记(二十七)对象序列化
  10. Myeclipse快键键
  11. 解决mysql分页数据错乱问题
  12. NS2仿真过程中需要的语言及基本组件
  13. qt QDir 枚举类型
  14. 一篇吃透前置加加和后置加加(附练习题)
  15. django3.0入门教程【三】:Hello,world!(完整踩坑笔记)
  16. FDD下行信道估计的一些知识点
  17. 全球与中国网络漫画市场行业市场规模分析及发展规划研究报告2022~2028年
  18. 虚拟服务器启动顺序,虚拟机开机启动项设置方法
  19. 【资源网站】推荐几个搜索资源网站
  20. 顺为、小米联合领投支出宝,官网启用三拼域名!

热门文章

  1. Uniapp设置顶部导航栏隐藏
  2. Python使用for循环完成剪刀石头布作业
  3. 抖音斜体加粗昵称生成网站源码
  4. 平民开发者和无代码,低代码开发
  5. Android 获取设备开机时间
  6. 高德地图荣获2016金瑞奖“最具成长力产品奖”
  7. 局部解剖学试题及答案
  8. Cesium获取当前点击位置坐标
  9. 华为devrun login活动参加心得
  10. bootstrap中col-xs-*在屏幕缩小时没起作用