【多线程】可重入锁 ReentrantLock
java除了使用关键字synchronized外,还可以使用ReentrantLock实现独占锁的功能。而且ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。
一、简介
ReentrantLock常常对比着synchronized来分析,我们先对比着来看然后再一点一点分析。
- synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。
- synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。
- synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以响应中断。
ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,一个最主要的就是ReentrantLock还可以实现公平锁机制。什么叫公平锁呢?也就是在锁上等待时间最长的线程将获得锁的使用权。通俗的理解就是谁排队时间最长谁先执行获取锁。
二、使用
1、简单使用
代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @description 可重入锁测试
* @author hzx
* @date 2022-04-01
*/
public class ReentrantLockTest {
private static final Lock lock = new ReentrantLock();
public static void main(String[] args) {
new Thread(() -> test(),"线程A").start();
new Thread(() -> test(),"线程B").start();
}
public static void test() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+"获取了锁");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName()+"释放了锁");
lock.unlock();
}
}
}
执行结果:
线程A获取了锁
线程A释放了锁
线程B获取了锁
线程B释放了锁
在这里我们定义了一个ReentrantLock,然后再test方法中分别lock和unlock,运行一边就可以实现我们的功能。这就是最简单的功能实现,代码很简单。我们再看看ReentrantLock和synchronized不一样的地方,那就是公平锁的实现。
2、公平锁实现
首先new一个ReentrantLock的时候参数为true,表明实现公平锁机制。公平锁的含义就是谁等的时间最长,谁就先获取锁。在这里我们多定义几个线程,然后在test方法中循环执行了两次加锁和解锁的过程。
代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @description 可重入锁测试(公平锁实现)
* @author hzx
* @date 2022-04-01
*/
public class ReentrantLockTest2 {
private static final Lock lock = new ReentrantLock(true);
public static void main(String[] args) {
new Thread(() -> test(),"线程1").start();
new Thread(() -> test(),"线程2").start();
new Thread(() -> test(),"线程3").start();
new Thread(() -> test(),"线程4").start();
new Thread(() -> test(),"线程5").start();
}
public static void test() {
for (int i = 0; i < 2; i++) {
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+"获取了锁");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
执行结果:
线程1获取了锁
线程2获取了锁
线程3获取了锁
线程4获取了锁
线程5获取了锁
线程1获取了锁
线程2获取了锁
线程3获取了锁
线程4获取了锁
线程5获取了锁
3、非公平锁实现
非公平锁那就随机的获取,谁运气好,cpu时间片轮到哪个线程,哪个线程就能获取锁,和上面公平锁的区别很简单,就在于先new一个ReentrantLock的时候参数为false,当然我们也可以不写,默认就是false。
代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @description 可重入锁测试(非公平锁实现)
* @author hzx
* @date 2022-04-01
*/
public class ReentrantLockTest3 {
private static final Lock lock = new ReentrantLock(false);
public static void main(String[] args) {
new Thread(() -> test(),"线程1").start();
new Thread(() -> test(),"线程2").start();
new Thread(() -> test(),"线程3").start();
new Thread(() -> test(),"线程4").start();
new Thread(() -> test(),"线程5").start();
}
public static void test() {
for (int i = 0; i < 2; i++) {
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+"获取了锁");
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
执行结果:
线程1获取了锁
线程2获取了锁
线程2获取了锁
线程3获取了锁
线程1获取了锁
线程3获取了锁
线程4获取了锁
线程4获取了锁
线程5获取了锁
线程5获取了锁
整个过程是随机的,没有固定的先后顺序,亲自测试时可以将for循环的次数增大,可以明显看出效果。
【多线程】可重入锁 ReentrantLock的更多相关文章
- Java多线程——深入重入锁ReentrantLock
简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...
- synchronized关键字,Lock接口以及可重入锁ReentrantLock
多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...
- Java 重入锁 ReentrantLock 原理分析
1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似.所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生 ...
- 轻松学习java可重入锁(ReentrantLock)的实现原理
转载自https://blog.csdn.net/yanyan19880509/article/details/52345422,(做了一些补充) 前言 相信学过java的人都知道 synchroni ...
- java 可重入锁ReentrantLock的介绍
一个小例子帮助理解(我们常用的synchronized也是可重入锁) 话说从前有一个村子,在这个村子中有一口水井,家家户户都需要到这口井里打水喝.由于井水有限,大家只能依次打水.为了实现家家有水喝,户 ...
- 轻松学习java可重入锁(ReentrantLock)的实现原理(转 图解)
前言 相信学过java的人都知道 synchronized 这个关键词,也知道它用于控制多线程对并发资源的安全访问,兴许,你还用过Lock相关的功能,但你可能从来没有想过java中的锁底层的机制是怎么 ...
- 17_重入锁ReentrantLock
[概述] 重入锁可以完全代替synchronized关键字. 与synchronized相比,重入锁ReentrantLock有着显示的操作过程,即开发人员必须手动指定何时加锁,何时释放锁,所以重入锁 ...
- Java 显示锁 之 重入锁 ReentrantLock(七)
ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁.另外,该锁还支持获取锁时的公平与非公平性的选择. 重入锁 ReentrantL ...
- 多线程通信的两种方式? (可重入锁ReentrantLock和Object)
(一)Java中线程协作的最常见的两种方式: (1)利用Object的wait().notify()和notifyAll()方法及synchronized (2)使用Condition.Reentra ...
- Java多线程系列——深入重入锁ReentrantLock
简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...
随机推荐
- 阿里云上安装 Ubuntu + MariaDB
阿里云上安装 Ubuntu + MariaDB 任务 安装第二个磁盘 设置第二个磁盘为数据盘 安装 MariaDB 配置 MariaDB 的数据文件目录 配置 MariaDB 远程访问 安装第二个磁盘 ...
- 浅谈Nodejs应用的主文件index.js的组成部分
前言 Node妹子的问世,着实让我们前端攻城狮兴奋了一把,尤其本屌听说Javascript可以写服务端后,兴奋的像是看到了二次元萝莉的胖子...(●'◡'●).呃哼...YY先到这里,原谅本屌是个二次 ...
- canvas实现平铺水印
欲实现的水印平铺的效果图如下: 从图上看,应该做到以下几点: 文字在X和Y方向上进行平铺: 文字进行了一定的角度的旋转: 水印作为背景,其z-index位置应位于页面内容底部, 即不能覆盖页面主内容: ...
- 第一天·浏览器内核及Web标准
一·浏览器及浏览器内核 1.常见的浏览器 (1)IE浏览器 IE是微软公司旗下浏览器,是目国内用户量最多的浏览器.IE诞生于1994年,当时微软为了对抗市场份额占据将近百分之九十的网景Netscape ...
- hbase增删查
代码: package cn.idcast.hbase; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.h ...
- jsp+servlet上传excel并将数据导入到数据库表的实现方法
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- Android开发小经验
1. TextView中的getTextSize返回值是以像素(px)为单位的, 而setTextSize()是以sp为单位的. 所以如果直接用返回的值来设置会出错,解决办法是 用setTextSiz ...
- mybatisPlus crud操作注意事项
1.调用IService里的update方法,如果是自定义根据除主键外其它字段更新的时候,如果给主键id设置其它值不会更新主键id,如果未设置主键id值或者设置为null,同样不会更新主键id. 2. ...
- C# 中托管内存与非托管内存之间的转换
c#有自己的内存回收机制,所以在c#中我们可以只new,不用关心怎样delete,c#使用gc来清理内存,这部分内存就是managed memory,大部分时候我们工作于c#环境中,都是在使用托管内存 ...
- 2021.11.02 eleveni的水省选题的记录
2021.11.02 eleveni的水省选题的记录 因为eleveni比较菜,所以eleveni决定从绿题开始水 --实际上菜菜的eleveni连绿题都不一定能水过/忍不住哭了 [P2217 HAO ...