2019独角兽企业重金招聘Python工程师标准>>>

ReentrantLock也能够让代码块原子执行,但是比synchronized更加强大,ReentrantLock具有嗅探锁定、多路分支通知等功能。 
嗅探锁定:是指获取锁时如果锁已经被其他线程获取到ReentrantLock可以进行指定等待时间获取锁或者 
多路分支通知:是指线程发生await时,线程可以选择注册在不同的监视器Condition对象上,在适当的时候可以选择指定的监视器Condition对象上的线程进行signal通知、执行

1、多线程执行同一代码块互斥

import java.util.concurrent.locks.ReentrantLock;class MyService {private ReentrantLock lock = new ReentrantLock();public void method() {try {lock.lock();for (int i = 1; i <= 3; i++) {Thread.sleep(1000);System.out.println("ThreadName=" + Thread.currentThread().getName() + "  " + i);}} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();}}
}class MyThread extends Thread {private MyService service;MyThread(MyService service) {this.service = service;}@Overridepublic void run() {service.method();}
}public class Test {public static void main(String[] args) {MyService service = new MyService();MyThread myThread1 = new MyThread(service);MyThread myThread2 = new MyThread(service);myThread1.start();myThread2.start();}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

结果 
ThreadName=Thread-0 1 
ThreadName=Thread-0 2 
ThreadName=Thread-0 3 
ThreadName=Thread-1 1 
ThreadName=Thread-1 2 
ThreadName=Thread-1 3

2、多线程执行不同代码块互斥


import java.util.concurrent.locks.ReentrantLock;class MyService {private ReentrantLock lock = new ReentrantLock();public void methodA() {lock.lock();try {System.out.println("MethodA begin ThreadName=" + Thread.currentThread().getName());for (int i = 1; i <= 3; i++) {System.out.println("ThreadName=" + Thread.currentThread().getName() + "  " + i);Thread.sleep(1000);}System.out.println("MethodA end ThreadName=" + Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public void methodB() {lock.lock();try {System.out.println("MethodB begin ThreadName=" + Thread.currentThread().getName());for (int i = 1; i <= 3; i++) {System.out.println("ThreadName=" + Thread.currentThread().getName() + "  " + i);Thread.sleep(1000);}System.out.println("MethodB end ThreadName=" + Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}
}class ThreadA extends Thread {private MyService service;ThreadA(MyService service) {this.service = service;}@Overridepublic void run() {service.methodA();}
}class ThreadB extends Thread {private MyService service;ThreadB(MyService service) {this.service = service;}@Overridepublic void run() {service.methodB();}
}public class Test {public static void main(String[] args) {MyService service = new MyService();ThreadA threadA = new ThreadA(service);threadA.setName("A");ThreadB threadB = new ThreadB(service);threadB.setName("B");threadA.start();threadB.start();}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

结果: 
MethodA begin ThreadName=A 
ThreadName=A 1 
ThreadName=A 2 
ThreadName=A 3 
MethodA end ThreadName=A 
MethodB begin ThreadName=B 
ThreadName=B 1 
ThreadName=B 2 
ThreadName=B 3 
MethodB end ThreadName=B

3、多路通知

当多线程进入await状态时,利用Condition监视器对不同类型线程通知

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;class MyService {private ReentrantLock lock = new ReentrantLock();private Condition conditionA = lock.newCondition();private Condition conditionB = lock.newCondition();public void methodA() {lock.lock();try {System.out.println("MethodA begin ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());conditionA.await();System.out.println("MethodA end ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public void methodB() {lock.lock();try {System.out.println("MethodB begin ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());conditionB.await();System.out.println("MethodB end ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public void signalA() {lock.lock();conditionA.signal();lock.unlock();}public void signalA_All() {lock.lock();conditionA.signalAll();lock.unlock();}public void signalB() {lock.lock();conditionB.signal();lock.unlock();}public void signalB_All() {lock.lock();conditionB.signalAll();lock.unlock();}
}class ThreadA extends Thread {private MyService service;ThreadA(MyService service) {this.service = service;}@Overridepublic void run() {service.methodA();}
}class ThreadB extends Thread {private MyService service;ThreadB(MyService service) {this.service = service;}@Overridepublic void run() {service.methodB();}
}public class Test {public static void main(String[] args) throws InterruptedException {MyService service = new MyService();ThreadA threadA = new ThreadA(service);threadA.setName("A");ThreadB threadB = new ThreadB(service);threadB.setName("B");threadA.start();threadB.start();Thread.sleep(1000);service.signalA();Thread.sleep(1000);service.signalB();//        ThreadA[] threadAs = new ThreadA[10];
//        for (int i=0;i<5;i++){
//            threadAs[i] = new ThreadA(service);
//        }
//        ThreadB[] threadBs = new ThreadB[10];
//        for (int i=0;i<5;i++){
//            threadBs[i] = new ThreadB(service);
//        }
//
//        for (int i=0;i<5;i++){
//            threadAs[i].start();
//            threadBs[i].start();
//        }
//
//        Thread.sleep(1000);
//        service.signalA_All();
//        Thread.sleep(1000);
//        service.signalB_All();}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123

测试结果1: 
MethodA begin ThreadName=A 1476800025028 
MethodB begin ThreadName=B 1476800025029 
MethodA end ThreadName=A 1476800026028 
MethodB end ThreadName=B 1476800027028

修改代码为:

 public static void main(String[] args) throws InterruptedException {MyService service = new MyService();
//        ThreadA threadA = new ThreadA(service);
//        threadA.setName("A");
//
//        ThreadB threadB = new ThreadB(service);
//        threadB.setName("B");
//        threadA.start();
//        threadB.start();
//
//        Thread.sleep(1000);
//        service.signalA();
//        Thread.sleep(1000);
//        service.signalB();ThreadA[] threadAs = new ThreadA[10];for (int i=0;i<5;i++){threadAs[i] = new ThreadA(service);}ThreadB[] threadBs = new ThreadB[10];for (int i=0;i<5;i++){threadBs[i] = new ThreadB(service);}for (int i=0;i<5;i++){threadAs[i].start();threadBs[i].start();}Thread.sleep(1000);service.signalA_All();Thread.sleep(1000);service.signalB_All();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

结果为: 
MethodA begin ThreadName=Thread-0 1476800227416 
MethodB begin ThreadName=Thread-7 1476800227417 
MethodB begin ThreadName=Thread-5 1476800227417 
MethodA begin ThreadName=Thread-3 1476800227418 
MethodA begin ThreadName=Thread-1 1476800227418 
MethodA begin ThreadName=Thread-4 1476800227418 
MethodB begin ThreadName=Thread-6 1476800227418 
MethodA begin ThreadName=Thread-2 1476800227418 
MethodB begin ThreadName=Thread-8 1476800227418 
MethodB begin ThreadName=Thread-9 1476800227418 
MethodA end ThreadName=Thread-0 1476800228419 
MethodA end ThreadName=Thread-3 1476800228419 
MethodA end ThreadName=Thread-1 1476800228419 
MethodA end ThreadName=Thread-4 1476800228420 
MethodA end ThreadName=Thread-2 1476800228420 
MethodB end ThreadName=Thread-7 1476800229419 
MethodB end ThreadName=Thread-5 1476800229419 
MethodB end ThreadName=Thread-6 1476800229419 
MethodB end ThreadName=Thread-8 1476800229419 
MethodB end ThreadName=Thread-9 1476800229419

4、公平所与非公平锁 
公平锁是指线程获(getting)取锁的顺序和线程锁定(got)的顺序相同,

Lock的一些方法说明 
A) getHoldCount() 
获取当前锁定(got)的个数 
B)getQueueLength() 
获取当前正在等待获取(getting)锁的线程数(Threads) 
C)getWaitQueueLength(Condition) 
返回等待(await)与此锁定(got)的Condition相关的个数

版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/jihaitaowangyi/article/details/52852693

转载于:https://my.oschina.net/u/1177694/blog/1635168

java 中Lock的使用相关推荐

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

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

  2. java lock的原理,Java中Lock原理探究

    在对于lock锁的使用上,很多人只是掌握了最基础的方法,但是对实现的过程不是很清楚.这里我们对lock锁功能的实现进行分析,以ReentrantLock为例,分析它的锁类型,并对相关的调用方法进行展示 ...

  3. 一文带你理解Java中Lock的实现原理

    转载自   一文带你理解Java中Lock的实现原理 当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题.java提供了两种方式来加锁,一种是关键字:synchron ...

  4. java中Lock锁的应用简介

    java中Lock锁的应用简介 整体描述 方法介绍 1. void lock() 2. boolean tryLock() 3. boolean tryLock(long timeout, TimeU ...

  5. java中lock底层实现_Synchronized与Lock的底层实现解析

    在JDK1.5之前,我们在编写并发程序的时候无一例外都是使用synchronized来实现线程同步的,而synchronized在JDK1.5之前同步的开销较大效率较低,因此在JDK1.5之后,推出了 ...

  6. 自旋锁和互斥锁的区别 java中lock Syntronized区别

    转载自:http://blog.csdn.net/susidian/article/details/51068858 自旋锁(Spin lock) 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠 ...

  7. java volatile lock_Java并发学习笔记 -- Java中的Lock、volatile、同步关键字

    Java并发 一.锁 1. 偏向锁 1. 思想背景 来源:HotSpot的作者经过研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同 一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁 ...

  8. Java高并发编程(五):Java中的锁Lock

    1. Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁).虽然它缺少了(通过synchr ...

  9. java lock unlock_详解Java中的ReentrantLock锁

    ReentrantLock锁 ReentrantLock是Java中常用的锁,属于乐观锁类型,多线程并发情况下.能保证共享数据安全性,线程间有序性 ReentrantLock通过原子操作和阻塞实现锁原 ...

最新文章

  1. BOS中常用方法和类
  2. 23,148,855,308,184,500是一个神奇的数字,还是纯粹的机会?
  3. 活动目录最佳实践分析器
  4. 非递归遍历二叉树(算法导论第三版第十章10.4-5)
  5. python fromhex_Python hexstring-list-str之间的转换方法
  6. spring笔记4-事务管理
  7. JAVA重要基础之反射
  8. java中aop和aoc的区别_你喝到的波尔多AOC、AOP红酒是真的吗?
  9. 生信技能树课程记录笔记(一)20220523
  10. 华为模拟器eNSP下载与安装(win10系统)
  11. python word 公式转png图片处理方式
  12. Centos 环境配置总结(持续更新)
  13. 流媒体技术介绍(中篇)
  14. android去掉开机锁屏,android 去掉锁屏
  15. 初学SQL 注入之常见的几种注入类型
  16. Win11搜索栏无法使用怎么办?
  17. X5045看门狗电路
  18. 【计算机硬件系统设计(华科)——三级时序 CPU「包含中断处理」(Logisim 实现)】
  19. SIT1040T,芯力特CAN接口芯片,参数描述,完美替代TJA1040
  20. 解决:Error while adding the mapper ‘interface *** to configuration. Error parsing Mapper XML.

热门文章

  1. 四大组建进程间通信--基础
  2. android Context的使用
  3. v8学习笔记(六) 汇编过程
  4. 在 Mac上压缩的压缩包 在windows上都会产生.DS_Store这种垃圾文件 怎么办
  5. (三)git常用命令及方法大全
  6. JVM学习笔记之-拉圾回收概述,垃圾回收相关算法
  7. jQuery的位置信息和事件
  8. 移动端功能测试需要注意的点
  9. flash、div、iframe的层级
  10. Direct3D 开发之旅 3D 游戏基本概念的介绍2