ReentrantLock示例说明
1、ReentrantLock锁
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Test_01 {
Lock lock = new ReentrantLock(); public static void main(String[] args) {
final Test_01 t = new Test_01();
new Thread(new Runnable() {
@Override
public void run() {
t.m1();
}
}).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
t.m2();
}
}).start();
} void m1() {
try {
lock.lock(); // 加锁
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println("m1() method " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 解锁
}
} void m2() {
lock.lock();
System.out.println("m2() method");
lock.unlock();
}
}
结果:
m1() method 0
m1() method 1
m1() method 2
m1() method 3
m1() method 4
m1() method 5
m1() method 6
m1() method 7
m1() method 8
m1() method 9
m2() method
2、ReentrantLock尝试锁
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Test_02 {
Lock lock = new ReentrantLock(); public static void main(String[] args) {
final Test_02 t = new Test_02();
new Thread(new Runnable() {
@Override
public void run() {
t.m1();
}
}).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
t.m2();
}
}).start();
} void m1() {
try {
lock.lock();
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println("m1() method " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} void m2() {
boolean isLocked = false;
try {
// 尝试锁, 如果有锁,无法获取锁标记,返回false。
// 如果获取锁标记,返回true
// isLocked = lock.tryLock(); // 阻塞尝试锁,阻塞参数代表的时长,尝试获取锁标记。
// 如果超时,不等待。直接返回。
isLocked = lock.tryLock(5, TimeUnit.SECONDS); if (isLocked) {
System.out.println("m2() method synchronized");
} else {
System.out.println("m2() method unsynchronized");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (isLocked) {
// 尝试锁在解除锁标记的时候,一定要判断是否获取到锁标记。
// 如果当前线程没有获取到锁标记,会抛出异常。
lock.unlock();
}
}
}
}
结果:
m1() method 0
m1() method 1
m1() method 2
m1() method 3
m1() method 4
m2() method unsynchronized
m1() method 5
m1() method 6
m1() method 7
m1() method 8
m1() method 9
3、ReentrantLock可打断锁
/**
* 可打断
* <p>
* 阻塞状态: 包括普通阻塞,等待队列,锁池队列。
* 普通阻塞: sleep(10000), 可以被打断。调用thread.interrupt()方法,可以打断阻塞状态,抛出异常。
* 等待队列: wait()方法被调用,也是一种阻塞状态,只能由notify唤醒。无法打断
* 锁池队列: 无法获取锁标记。不是所有的锁池队列都可被打断。
* 使用ReentrantLock的lock方法,获取锁标记的时候,如果需要阻塞等待锁标记,无法被打断。
* 使用ReentrantLock的lockInterruptibly方法,获取锁标记的时候,如果需要阻塞等待,可以被打断。
*/
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Test_03 {
Lock lock = new ReentrantLock(); public static void main(String[] args) {
final Test_03 t = new Test_03();
new Thread(new Runnable() {
@Override
public void run() {
t.m1();
}
}).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
t.m2();
}
});
t2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt();// 打断线程休眠。非正常结束阻塞状态的线程,都会抛出异常。
} void m1() {
try {
lock.lock();
for (int i = 0; i < 5; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println("m1() method " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} void m2() {
try {
lock.lockInterruptibly(); // 可尝试打断,阻塞等待锁。可以被其他的线程打断阻塞状态
System.out.println("m2() method");
} catch (InterruptedException e) {
System.out.println("m2() method interrupted");
} finally {
try {
lock.unlock();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结果:
m1() method 0
m1() method 1
java.lang.IllegalMonitorStateException
m2() method interrupted
at java.base/java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:149)
at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1300)
at java.base/java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:439)
at concurrent.t03.Test_03.m2(Test_03.java:72)
at concurrent.t03.Test_03$2.run(Test_03.java:37)
at java.base/java.lang.Thread.run(Thread.java:844)
m1() method 2
m1() method 3
m1() method 4
4、ReentrantLock公平锁
/*
*在公平的锁上,线程按照他们发出请求的顺序获取锁,但在非公平锁上,则允许‘插队’:当一个线程请求非公平锁时,如果在发出请求的同时该锁变成可用状态,那么这个线程会跳过队列中所有的等待线程而获得锁。
非公平的ReentrantLock 并不提倡插队行为,但是无法防止某个线程在合适的时候进行插队。
*在公平的锁中,如果有另一个线程持有锁或者有其他线程在等待队列中等待这个所,那么新发出的请求的线程将被放入到队列中。而非公平锁上,只有当锁被某个线程持有时,新发出请求的线程才会被放入队列中。
*非公平锁性能高于公平锁性能的原因:
*在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。
*假设线程A持有一个锁,并且线程B请求这个锁。由于锁被A持有,因此B将被挂起。当A释放锁时,B将被唤醒,因此B会再次尝试获取这个锁。与此同时,如果线程C也请求这个锁,那么C很可能会在B被完全唤醒之前获得、使用以及释放这个锁。这样就是一种双赢的局面:B获得锁的时刻并没有推迟,C更早的获得了锁,并且吞吐量也提高了。
*当持有锁的时间相对较长或者请求锁的平均时间间隔较长,应该使用公平锁。在这些情况下,插队带来的吞吐量提升(当锁处于可用状态时,线程却还处于被唤醒的过程中)可能不会出现。
**/
import java.util.concurrent.locks.ReentrantLock; public class Test_04 { public static void main(String[] args) {
TestReentrantlock t = new TestReentrantlock();
//TestSync t = new TestSync();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
t2.start();
}
} class TestReentrantlock extends Thread {
// 定义一个公平锁
private static ReentrantLock lock = new ReentrantLock(true); public void run() {
for (int i = 0; i < 5; i++) {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " get lock in TestReentrantLock");
} finally {
lock.unlock();
}
}
} } class TestSync extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + " get lock in TestSync");
}
}
}
}
结果(ReentrantLock两种都与可能,但是TestSync只可能出现后一种):
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-1 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
Thread-2 get lock in TestReentrantlock
ReentrantLock示例说明的更多相关文章
- Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock
本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...
- java多线程 ReentrantLock
本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...
- Java - "JUC" ReentrantLock获取锁
[Java并发编程实战]-----“J.U.C”:ReentrantLock之一简介 ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”. 顾名思义,R ...
- ReentrantLock源码学习总结 (一)
[^ ]: 以下源码分析基于JDK1.8 ReentrantLock 示例 private ReentrantLock lock = new ReentrantLock(true); public v ...
- ReentrantLock源码学习总结 (二)
[^]: 以下源码分析基于JDK1.8 ReentrantLock 示例 private ReentrantLock lock = new ReentrantLock(true); public vo ...
- Java锁--ReentrantLock
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3496101.html ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又 ...
- 多线程编程-- part5.1 互斥锁ReentrantLock
ReentrantLock简介 Reentrantlock是一个可重入的互斥锁,又被称为独占锁. Reentrantlock:分为公平锁和非公平锁,它们的区别体现在获取锁的机制上是否公平.“锁”是为了 ...
- 3.并发编程-ReentrantLock 细节说明
并发编程-ReentrantLock 细节说明 ---title: 并发编程-ReentrantLock 细节说明date: 2018-07-05 09:06:57categories: - 并发编程 ...
- 干货,深入剖析ReentrantLock源码,推荐收藏
ReentrantLock和Synchronized都是Java开发中最常用的锁,与Synchronized这种JVM内置锁不同的是,ReentrantLock提供了更丰富的语义.可以创建公平锁或非公 ...
随机推荐
- atom插件
1.Sync Settings 搭配github,同步你的atom插件信息,配置信息,让你轻松实现一台电脑配置,多台电脑共享. 2.Emmet 能够基于Emmet语法产生HTML,做过前段开发的不会不 ...
- (转)SQLServer分区表操作
原文地址:https://www.cnblogs.com/libingql/p/4087598.html 1. 分区表简介 分区表在逻辑上是一个表,而物理上是多个表.从用户角度来看,分区表和普通表是一 ...
- Linq to SQL -- Union All、Union、Intersect和Top、Bottom和Paging和SqlMethods
Union All/Union/Intersect操作 适用场景:对两个集合的处理,例如追加.合并.取相同项.相交项等等. Concat(连接) 说明:连接不同的集合,不会自动过滤相同项:延迟. 1. ...
- 部署redis4.0-cluster
一.部署环境 .关闭iptables(firewalld)或添加放行规则 .关闭selinux3.部署redis实例,参考:https://www.cnblogs.com/panwenbin-logs ...
- leetcode每日刷题计划-简单篇day13
Num 169 先码,回头再说,摩尔算法... tle了 class Solution { public: int majorityElement(vector<int>& num ...
- HTTPS 基本流程2
Https在真正请求数据前,先会与服务有几次握手验证,以证明相互的身份,以下图为例 2.1 验证流程 注:文中所写的序号与图不对应但流程是对应的 1 客户端发起一个https的请求,把自身支持的一系 ...
- javascript基础知识笔记-自用
笔记内容根据个人基础知识不足不明白之处做的记录.主要看的:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 1.变量,变量的名字又叫标识符 ...
- 超简单(两步)-微信怎么实现打开外部浏览器,下载app,打开网页URL
现在微信渠道可以说是拉新最快的渠道,因为微信具备强裂变性.但是目前微信对第三方下载链接的拦截是越来越严格了,那么想要在微信内肆无忌惮地推广链接就需要用到微信跳转浏览器的接口,那如何获取该接口呢? ...
- 干货!微信自动跳转默认浏览器下载app的方法!
现在微信渠道可以说是拉新最快的渠道,因为微信具备强裂变性.但是目前微信对第三方下载链接的拦截是越来越严格了,那么想要在微信内肆无忌惮地推广链接就需要用到微信跳转浏览器的接口,那如何获取该接口呢? ...
- LevelDB源码分析-Bloom Filter
Bloom Filter bloom filter是leveldb中用来在一个block中检测key是否存在的工具,主要在BloomFilterPolicy类中实现: class BloomFilte ...