ReentrantLock简介

ReentrantLock是一个可重复的互斥锁,又被称为独占锁,可重入的意思是:ReentrantLock锁可以被单个线程多次获取。但是在同一个时间点只能被一个线程锁持有

ReentrantLock使用一个FIFO(先进先出)的等待队里来管理获取该锁所有线程的。

ReentrantLock是一个独占锁,在获取锁的之后其所有的操作都是线程独享的,其他的线程在没有获取到锁之前都需要等待。

public class ReentrantLock implements Lock,java.io.Serializable

ReentrantLock之中分为公平锁与非公平锁,它们的区别体现在获取锁的机制上是否公平以及执行速度上。、

这两种锁的启用也是非常容易控制的,这个类提供的构造方法如下:

  • 无参构造(非公平锁,NonfairSync)

    public ReentrantLock() {
    sync = new NonfairSync();
    }
  • 有参构造
    public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
    }
    //fair = true,表示公平锁,FairSync
    //fair = false,表示非公平锁,NonfairSync

ReentrantLock继承结构

范例:使用ReentrantLock定义一个多线程卖票的处理程序

package so.strong.mall.concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; class Ticket {
private Lock myLock = new ReentrantLock(); //非公平锁
private int count = 10; //一共10张票
public void sale() {
myLock.lock(); //进入到阻塞状态,一直到unlock执行后解除阻塞
try {
if (this.count > 0) {
System.out.println(Thread.currentThread().getName() + "卖票,ticket=" + this.count--);
}
} finally {
myLock.unlock(); //不管最终结果如何一定要进行解锁
}
}
} public class TestDemo {
public static void main(String[] args) {
final Ticket ticket = new Ticket(); //多线程要共享同一个数据资源
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
ticket.sale(); //卖票处理
}
}
}).start();
}
}
}
Thread-0卖票,ticket=10
Thread-0卖票,ticket=9
Thread-0卖票,ticket=8
Thread-0卖票,ticket=7
Thread-0卖票,ticket=6
Thread-0卖票,ticket=5
Thread-0卖票,ticket=4
Thread-2卖票,ticket=3
Thread-2卖票,ticket=2
Thread-2卖票,ticket=1

当前的代码要比直接使用synchronized更加容易,而且锁的处理机制更加的直观。通过查看源代码可以发现,使用lock()进行锁定的时候会考虑两种情况:

Sync-java.util.concurrent.locks.ReentrantLock

  • FairSync-java.util.concurrent.locks.ReentrantLock
  •  NonFairSync-java.util.concurrent.locks.ReentrantLock

在进行公平锁处理的时候每当锁定一个线程对象就会使用“acquire(1)”方法进行表示:

final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}

在进行解锁时会使用一个"sync.release(1)”释放方法, 1 表示释放一个:

public void unlock() {
sync.release(1);
}

JUC——线程同步锁(ReentrantLock)的更多相关文章

  1. JUC——线程同步锁(Condition精准控制)

    在进行锁处理的时候还有一个接口:Condition,这个接口可以由用户来自己进行锁的对象创建. Condition的作用是对锁进行更精确的控制. Condition的await()方法相当于Objec ...

  2. JUC——线程同步锁(锁处理机制简介)

    锁处理机制简介 juc的开发框架解决的核心问题是并发访问和数据安全操作问题,当进行并发访问的时候如果对于锁的控制不当,就会造成死锁这样的阻塞问题. 为了解决这样的缺陷,juc里面重新针对于锁的概念进行 ...

  3. JUC——线程同步锁(ReentrantReadWriteLock读写锁)

    读写锁简介 所谓的读写锁值得是两把锁,在进行数据写入的时候有一个把“写锁”,而在进行数据读取的时候有一把“读锁”. 写锁会实现线程安全同步处理操作,而读锁可以被多个对象读取获取. 读写锁:ReadWr ...

  4. JUC——线程同步锁(LockSupport阻塞原语)

    java.util.concurrent.locks.LockSupport这个是一个独立的类,这个类的主要功能是用来解决Thread里面提供的suspend()(挂起线程).resume()(恢复运 ...

  5. Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量

    在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...

  6. 同步锁——ReentrantLock

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 Lock接口简介 在JUC包下面有一个java.util ...

  7. Java 基础【07】线程同步锁的选择

    在需要线程同步的时候如何选择合适的线程锁? 例:选择可以存入到常量池当中的对象,String对象等 public class SyncTest { private String name = &quo ...

  8. 多线程 - 线程同步锁(lock、Monitor)

    1. 前言 多线程编程的时候,我们不光希望两个线程间能够实现逻辑上的先后顺序运行,还希望两个不相关的线程在访问同一个资源的时候,同时只能有一个线程对资源进行操作,否则就会出现无法预知的结果. 比如,有 ...

  9. java基础---Java---面试题---银行业务调度系统(线程同步锁、枚举、线程池)

    银行业务调度系统的项目需求:   模拟实现银行业务调度系统逻辑,具体需求如下:   Ø 银行内有6个业务窗口,1- 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口.   Ø 有三种对应类 ...

随机推荐

  1. AOP-方法拦截器-笔记

    方法拦截器的继承层次图: 这些拦截器具体长什么样?? 一.MethodBeforeAdviceInterceptor 这个拦截器只有一个属性就是前置通知.需要注意的是前置通知和返回通知的拦截器才会持有 ...

  2. ubuntu配置默认python版本并安装pip

    ubuntu 16.04本身是自带python的,他本身是自带2.X和3.X,两个版本,默认的是2.X.这里记录一下如果在版本间切换以及如何把python版本切换到3.X下的方法. 1.查看Ubunt ...

  3. Mac生成APP图标和启动图的脚本

    概述 之前用的一个批量导出APP图标和启动图的软件,今天发现收费了,于是自己造了个简单的轮子. 实现 Mac上的sips命令,可以很方便的帮助用户修改图片尺寸 Xcode里面的APP启动图资源包含两部 ...

  4. Mac端 Open GL初探

    一.环境配置 1.创建macOS工程 2.添加OpenGL.framework和GLUT.framework两个系统库 3.拖入资源文件 如果libGLTools.a问价先拖入到工程其他位置,后再移到 ...

  5. rdlc报表随笔心得 ,基本结构和一些表达式。

    Dataset Form RDLC 主要放数据集的文件夹 存放窗体的文件夹 存放各种报表的文件夹 第一部,创建报表结构 首先添加数据集项 添加完成之后我们会看到这个页面 之后我们在上面添加一些数据集 ...

  6. Linux服务-mysql基础篇

    目录 1. 关系型数据库介绍 1.1 数据结构模型 1.2 RDBMS专业名词 1.3 关系型数据库的常见组件 1.4 SQL语句 2. mysql安装与配置 2.1 mysql安装 2.2 mysq ...

  7. 存储类、链接和内存管理(c prime plus)

    首先介绍三个概念: (1)作用域:作用域描述了程序中可以访问一个标识符的一个或多个区域. 一共有三种作用域:代码块作用域.函数原型作用域和文件作用域 a.代码块作用域:一个代码块是包含在开始花括号和对 ...

  8. 从0开始学golang--2.2--如何去爬园子的数据👉进阶篇,面向对象的单任务版

    执行页main.go-----------------------------------代码

  9. 小白日记53:kali渗透测试之Web渗透-SSL、TLS中间人攻击(SSLsplit,Mitmproxy,SSLstrip),拒绝服务攻击

    SSL.TLS中间人攻击 SSL中间人攻击 攻击者位于客户端和服务器通信链路中 利用方法: ARP地址欺骗 修改DHCP服务器 (存在就近原则) 手动修改网关 修改DNS设置 修改HOSTS文件[高于 ...

  10. python基础学习1-第一个网络爬虫程序

    #!/usr/bin/env python # -*- coding:utf-8 -*- 煎蛋网抓妹子图 import urllib.request import os import random d ...