获取锁定

  • void lock():常用获取锁定的方法
  • void lockInterruptibly():如果当前线程未被中断,则获取锁定;如果当前线程被中断,则出现异常
  • boolean tryLock():调用时锁定未被另一个线程持有的情况下,才会获取该锁定
  • boolean tryLock(long timeOut,TimeUnit unit):如果锁定在给定时间内未被另一个线程持有,且当前线程未被中断,则获取该锁定

lock()方法

 public class Run {
private ReentrantLock lock = new ReentrantLock(); public void testLock(){
try {
lock.lock(); for (int i = 0; i < 5; i++) {
System.out.println("ThreadName = "+Thread.currentThread().getName()+", i = "+(i+1));
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕,当前时间:"+System.currentTimeMillis());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Run run = new Run();
run.testLock(); Runnable runnable = new Runnable() {
@Override
public void run() {
run.testLock();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
}

----------------------------------------------------console----------------------------------------------------

ThreadName = main, i = 1
ThreadName = main, i = 2
ThreadName = main, i = 3
ThreadName = main, i = 4
ThreadName = main, i = 5
main线程执行完毕,当前时间:1539138509575
ThreadName = A, i = 1
ThreadName = A, i = 2
ThreadName = A, i = 3
ThreadName = A, i = 4
ThreadName = A, i = 5
A线程执行完毕,当前时间:1539138510587
ThreadName = B, i = 1
ThreadName = B, i = 2
ThreadName = B, i = 3
ThreadName = B, i = 4
ThreadName = B, i = 5
B线程执行完毕,当前时间:1539138511587

lockInterruptibly()方法

 public class Run2 {
private ReentrantLock lock = new ReentrantLock();
public void testLockInterruptibly(){
try {
lock.lockInterruptibly();
System.out.println("ThreadName = "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(lock.isHeldByCurrentThread()){//查询当前线程是否保持锁定
lock.unlock();
}
}
} public static void main(String[] args) {
Run2 run2 = new Run2();
Runnable runnable = new Runnable() {
@Override
public void run() {
run2.testLockInterruptibly();
}
};
Thread t1 = new Thread(runnable);
t1.setName("T1");
t1.start(); Thread t2 = new Thread(runnable);
t2.setName("T2");
t2.start();
t2.interrupt();
}
}

----------------------------------------------------console----------------------------------------------------

java.lang.InterruptedException
ThreadName = T1
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at com.qf.test12.t.Run2.testLockInterruptibly(Run2.java:13)
at com.qf.test12.t.Run2$1.run(Run2.java:29)
at java.lang.Thread.run(Thread.java:748)

tryLock()方法

 public class Run3 {
private ReentrantLock lock = new ReentrantLock();
public void testTryLock(){//只获取锁定,不释放锁定
if(lock.tryLock()){
System.out.println(Thread.currentThread().getName()+"获得锁");
}else {
System.out.println(Thread.currentThread().getName()+"未获得锁");
}
} public static void main(String[] args) {
Run3 run3 = new Run3();
Runnable runnable = new Runnable() {
@Override
public void run() {
run3.testTryLock();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
}

----------------------------------------------------console----------------------------------------------------

A获得锁
B未获得锁

tryLock(long timeOut,TimeUnit unit)方法

 public class Run3 {
private ReentrantLock lock = new ReentrantLock();
public void testTryLock(){
try {
if(lock.tryLock(3, TimeUnit.SECONDS)){
System.out.println(Thread.currentThread().getName()+"获得锁");
Thread.sleep(4000);//有一个未获得锁
//Thread.sleep(2000);//两个都获得锁
}else {
System.out.println(Thread.currentThread().getName()+"未获得锁");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(lock.isHeldByCurrentThread()){
lock.unlock();
}
}
} public static void main(String[] args) {
Run3 run3 = new Run3();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行,当前时间:"+System.currentTimeMillis());
run3.testTryLock();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
}

----------------------------------------------------console----------------------------------------------------

--------------------Thread.sleep(4000)-------------------
A执行,当前时间:1539141085501
B执行,当前时间:1539141085501
B获得锁
A未获得锁
--------------------Thread.sleep(2000)-------------------
A执行,当前时间:1539141269380
B执行,当前时间:1539141269380
A获得锁
B获得锁

其他常用方法

getXxx方法

  • int getHoldCount()方法:查询当前线程保持此锁定的个数,即当前线程调用lock()方法的次数
  • int getQueueLength()方法:返回正在等待此锁定的线程估计数
  • int getWaitQueueLength(Condition condition)方法:返回等待与此锁定相关的给定条件的线程估计数

hasXxx方法

  • boolean hasQueuedThread(Thread thread)方法:查询指定线程是否正在等待获取此锁定
  • boolean hasQueuedThreads()方法:查询是否有线程正在等待此锁定
  • boolean hasWaiters(Condition condition)方法:查询是否有线程正在等待与此锁定有关的condition条件

isXxx方法

  • boolean isFair()方法:判断是不是公平锁
  • boolean isHeldByCurrentThread()方法:查询当前线程是否保持此锁定
  • boolean isLocked()方法:判断此锁定是否由任意线程保持

Condition的几个方法

  • awaitUninterruptibly()方法:调用该方法的前提是,当前线程已经成功获得与该条件对象绑定的重入锁,否则调用该方法时会抛出IllegalMonitorStateException。调用该方法后,结束等待的唯一方法是其它线程调用该条件对象的signal()或signalALL()方法。等待过程中如果当前线程被中断,该方法仍然会继续等待,同时保留该线程的中断状态。
  • awaitNanos(long nanosTimeout) 方法:调用该方法的前提是,当前线程已经成功获得与该条件对象绑定的重入锁,否则调用该方法时会抛出IllegalMonitorStateException。nanosTimeout指定该方法等待信号的的最大时间(单位为纳秒)。若指定时间内收到signal()或signalALL()则返回nanosTimeout减去已经等待的时间;若指定时间内有其它线程中断该线程,则抛出InterruptedException并清除当前线程的打断状态;若指定时间内未收到通知,则返回0或负数
  • awaitUntil(Date deadline) 方法:适用条件与行为与awaitNanos(long nanosTimeout)完全一样,唯一不同点在于它不是等待指定时间,而是等待由参数指定的某一时刻,等待时间到达前可以被其他线程提前唤醒

ReentrantLock的相关方法使用的更多相关文章

  1. 通过ReentrantLock源代码分析AbstractQueuedSynchronizer独占模式

    1. 重入锁的概念与作用       reentrant 锁意味着什么呢?简单来说,它有一个与获取锁相关的计数器,如果已占有锁的某个线程再次获取锁,那么lock方法中将计数器就加1后就会立刻返回.当释 ...

  2. 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()

    最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...

  3. 透过ReentrantLock窥探AQS

    背景 JDK1.5引入的并发包提供了一系列支持中等并发的类,这些组件是一系列的同步器,几乎任一同步器都可以实现其他形式的同步器,例如,可以用可重入锁实现信号量或者用信号量实现可重入锁.但是,这样做带来 ...

  4. 基于ReentrantLock的非公平锁理解AQS

    AQS AQS概述 ​ AbstractQueuedSynchronizer抽象队列同步器简称AQS,它是实现同步器的基础组件,juc下面Lock的实现以及一些并发工具类就是通过AQS来实现的,这里我 ...

  5. B9 Concurrent 重入锁(ReentrantLock)

    [概述] java.util.concurrent.locks.ReentrantLock 实现 java.util.concurrent.locks.Lock 接口,加锁(lock)和 解锁(unl ...

  6. ReentrantLock 源码分析以及 AQS (一)

    前言 JDK1.5 之后发布了JUC(java.util.concurrent),用于解决多线程并发问题.AQS 是一个特别重要的同步框架,很多同步类都借助于 AQS 实现了对线程同步状态的管理. A ...

  7. Java读源码之ReentrantLock(2)

    前言 本文是 ReentrantLock 源码的第二篇,第一篇主要介绍了公平锁非公平锁正常的加锁解锁流程,虽然表达能力有限不知道有没有讲清楚,本着不太监的原则,本文填补下第一篇中挖的坑. Java读源 ...

  8. Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)

    AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...

  9. 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

    ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...

随机推荐

  1. [FW]使用kprobes查看内核内部信息

    使用printk打印变量等方法,是调试内核的有效方法之一,但是这种方法必须重新构建并用新内核启动,调试效率比较低.以内核模块的方式使用kprobes.jprobes,就可以在任意地址插入侦测器,执行包 ...

  2. springboot中xml配置之@ImportResource

    springboot中进行相关的配置往往有java配置和xml配置两种方式. 使用java的方式配置只需要使用@configuration注解即可,而使用xml的方式配置的话需要使用@ImportRe ...

  3. 【知识强化】第六章 应用层 6.3 文件传输协议FTP

    这节课我们来学习一下文件传输协议FTP. 我们知道一个文件的传输过程呢一定需要协议的规定,那在文件传送协议这一块呢有很多个协议.比较主要的两个一个是文件传送协议FTP,一个是简单文件传送协议TFTP. ...

  4. go语言从例子开始之Example14.变参函数

    可变参数函数.可以用任意数量的参数调用.例如,fmt.Println 是一个常见的变参函数. Example: package main import "fmt" //...int ...

  5. Mac利用分屏spliter

    有时候一台电脑学习很鸡肋,特别是在照葫芦画瓢阶段,只能来回的切换页面,效率极其低下,一直希望可以将其分别显示,互不干扰.今天在mac发现此方法,大大提高了学习效率,所以今天分享给大家: 方法一:长按窗 ...

  6. function的各做写法

    function(){}()让变量快速初始化结果 var timestamp = function(){ var timestamp = Date.parse(new Date()); return ...

  7. 【leetcode】991. Broken Calculator

    题目如下: On a broken calculator that has a number showing on its display, we can perform two operations ...

  8. Halo(三)

    接口中可以定义方法 1. 定义静态方法(直接调用) public interface Test { public static void method() { /** * 1.定义一个静态的带有方法体 ...

  9. 根据mysql数据库 定义solr Schema.xml中配置业务域

    <!--product--> <field name="product_name" type="text_ik" indexed=" ...

  10. 【Flutter学习】事件处理与通知之事件处理

    一,概述 移动应用中一个必不可少的环节就是与用户的交互,在Flutter中提供的手势检测为GestureDetector. Flutter中的手势系统分为二层: 第一层是触摸原事件(指针) Point ...