当前位置:网站首页>多线程05--Lock
多线程05--Lock
2022-07-22 10:44:00 【fengxianaa】
上一篇:多线程04--线程的原子性、CAS_fengxianaa的博客-CSDN博客
1. 基础概念
/**
* Lock:是一个接口,jdk1.5后的另一种加锁方式
*
* 有了 synchronized,那为什么还需要Lock?
* 1. 使用 synchronized,如果其中代码执行的速度特别慢,其他线程便只能干巴巴地等待,非常影响程序执行效率。
* 而 Lock 可以做到只等待一定的时间,如果还获取不到锁,就去做其他事情。
*
* 2. 使用 synchronized,当多个线程执行读操作时,依然会阻塞,但其实,读和读之间是不冲突的
* 而 Lock 可以做到多个读线程之间不阻塞
*
* ReentrantLock:可重入锁,是 Lock 的代表实现类
*/
public class Lock01_ReentrantLock01 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
new Thread(() ->{
lock.lock();//加锁
try {
System.out.println(Thread.currentThread().getName() + "加锁后执行。。。。。。");
ThreadHelper.sleep(3000);
} finally {
//释放锁,为了保证Lock锁一定会释放,所以要在finally中加上这句代码
lock.unlock();
}
}).start();
ThreadHelper.sleep(3000);
new Thread(() ->{
lock.lock();//加锁
System.out.println(Thread.currentThread().getName() + "加锁后执行。。。。。。");
lock.unlock();//释放锁,为了保证Lock锁一定会释放,所以要在finally中加上这句代码
}).start();
}
}
2. 基础方法
/**
* ReentrantLock 常用方法
* lock()
* 阻塞当前线程,直到获取锁,阻塞时,调用interrupt没用
*
* lockInterruptibly()
* 判断线程是否已中断
* 是:报 InterruptedException
* 否:阻塞当前线程,直到获取锁,阻塞时,如果调用interrupt,报 InterruptedException
*
* unlock()
* 释放锁
*
*/
public class Lock01_ReentrantLock02 {
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
new Thread(() ->{
lock.lock();//加锁
System.out.println(Thread.currentThread().getName() + "加锁后执行。。。。。。");
ThreadHelper.sleep(3000);
lock.unlock();//释放锁,为了保证Lock锁一定会释放,所以要在finally中加上这句代码
}).start();
ThreadHelper.sleep(500);
Thread t = new Thread(() ->{
lock.lock();//加锁
// lock.lockInterruptibly();//中断时,抛出 InterruptedException
System.out.println(Thread.currentThread().getName() + "加锁后执行。。。。。。");
lock.unlock();
});
t.start();
ThreadHelper.sleep(100);
t.interrupt();
}
}
常用方法:
/**
* ReentrantLock 常用方法
* tryLock()
* 尝试获取锁,该方法不阻塞线程
* 成功:true
* 失败:false
*
* tryLock(long timeout, TimeUnit unit)
* 在指定时间内阻塞线程,直到获取锁,阻塞时,如果调用interrupt,报 InterruptedException
* 成功:true
* 失败:false
*
*/
public class Lock01_ReentrantLock03 {
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
new Thread(() ->{
lock.lock();//加锁
System.out.println(Thread.currentThread().getName() + "加锁后执行。。。。。。");
ThreadHelper.sleep(3000);
lock.unlock();//释放锁,为了保证Lock锁一定会释放,所以要在finally中加上这句代码
}).start();
ThreadHelper.sleep(500);
Thread t = new Thread(() ->{
boolean bool = lock.tryLock();//尝试获取锁
// boolean bool = lock.tryLock(5, TimeUnit.SECONDS);
if(bool){
System.out.println(Thread.currentThread().getName() + "加锁后执行。。。。。。");
lock.unlock();
}else{
System.out.println(Thread.currentThread().getName() + "没有拿到锁。。。。。。");
}
});
t.start();
ThreadHelper.sleep(100);
t.interrupt();
}
}
Condition
/**
* Condition:配合Lock,唤醒指定的线程
*
* await()
* 当前线程等待被唤醒,等待时候释放锁,如果等待时被interrupt,抛出 InterruptedException
*
* signal()
* 唤醒调用 await() 方法的线程,当前线程释放锁后,调用 await() 方法的线程会继续执行
* 如果有好几个线程都调用了 await(),那么唤醒等待时间最长的
*
* signalAll()
* 当前线程释放锁后,唤醒所有调用 await() 方法的线程
*/
public class Lock01_ReentrantLock04 {
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
Condition one = lock.newCondition();
new Thread(() -> {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "加锁后等待。。。。。。");
one.await();//线程等待,等待时候释放锁,当调用one.signal()之后,继续往下执行
System.out.println(Thread.currentThread().getName() + "苏醒,继续执行。。。。。。。。。。。。");
} catch (Exception e) {
} finally {
lock.unlock();
}
},"线程A").start();
ThreadHelper.sleep(3000);
new Thread(() -> {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "加锁后等待。。。。。。");
one.await();//线程等待,等待时候释放锁,当调用one.signal()之后,继续往下执行
System.out.println(Thread.currentThread().getName() + "苏醒,继续执行。。。。。。。。。。。。");
} catch (Exception e) {
} finally {
lock.unlock();
}
},"线程B").start();
ThreadHelper.sleep(5000);
new Thread(() -> {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "执行one.signal()。。。。。。");
// one.signal();//这时候线程A、B,都在等待,当线程C释放锁后,等待时间最长的继续运行
one.signalAll();
ThreadHelper.sleep(3000);
} catch (Exception e) {
} finally {
lock.unlock();
}
},"线程C").start();
}
}
3. 公平锁和非公平锁
/**
* 公平锁和非公平锁
* 公平锁: 讲究先来后到。比如,同时有多个线程在等待一个锁,当锁被释放时,等待时间最久的线程(最先请求的线程)会获得锁,现实场景:排队买票
* 非公平锁: 谁抢到就是谁的,可能导致某个线程一直抢不到锁
*
* synchronized 的本质就是非公屏锁
*/
public class Lock01_ReentrantLock05 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();//默认非公屏锁
lock = new ReentrantLock(true);//公平锁
}
}
4. ReadWriteLock
/**
* ReadWriteLock 读写锁,也是一个接口
*
* ReentrantReadWriteLock 可重入的读写锁,是ReadWriteLock的主要实现类
* 允许多个读线程同时访问,但不允许写和读、写和写同时访问。
* 相对于 ReentrantLock (排他锁),提高了并发性
*
*/
public class Lock02_ReadWriteLock01 {
public static void main(String[] args) throws InterruptedException {
ReadWriteLock lock = new ReentrantReadWriteLock();
/**
* 1. 多个线程竞争读锁,不会产生阻塞
*/
for(int i=0;i<2;i++){
new Thread(() -> {
lock.readLock().lock();//使用读锁
System.out.println(Thread.currentThread().getName()+"拿到了读锁。。。。。。");
ThreadHelper.sleep(3000);
lock.readLock().unlock();// 实际中,这句代码需要放到 finally 中
}).start();
}
/**
* 2. 多个线程竞争写锁,会产生阻塞
*/
// for(int i=0;i<2;i++){
// new Thread(() -> {
// lock.writeLock().lock();
// System.out.println(Thread.currentThread().getName()+"拿到了写锁。。。。。。");
// ThreadHelper.sleep(3000);
// lock.writeLock().unlock();// 实际中,这句代码需要放到 finally 中
// }).start();
// }
/**
* 3. 锁降级:写锁——>读锁,即 同一个线程先获取写锁,还没释放,仍然可以继续获取读锁
*/
// lock.writeLock().lock();
// System.out.println("主线程获取了写锁。。。。。。");
// lock.readLock().lock();
// System.out.println("主线程又获取了读锁。。。。。。");
// lock.readLock().unlock();
// lock.writeLock().unlock();
}
}
边栏推荐
- Function principle of pytoch network training process: source code analysis optimizer.zero_ grad()loss.backward()optimizer.step()
- Airtest 进行WebUI自动化测试(selenium)
- C language (Itoa function)
- 【面试:基础篇03:选择排序】
- Pastel: parasitic matching drive layout and wiring of capacitor array with generalized ratio in charge redistribution sar-adc
- 【面试:基础篇01:整数二分查找】
- scanf和printf格式问题
- 链表的基本操作
- Notes: C language
- 1057 stack (30 points)
猜你喜欢
网络基础知识
Leetcode high frequency question: what is the difference between the combat effectiveness of the two soldiers with the closest combat effectiveness of N soldiers in the challenge arena
LeetCode高频题:擂台赛n名战士战斗力最接近的两名战士,战斗力之差为多少
[literature reading and thought notes 14] beyond a Gaussian noise: residual learning of deep CNN for image recognition
DEFORMABLE DETR 论文精度,并解析网络模型结构
测试相关基础概念
【FPGA】:ip核--ibert
Canny based subpixel severity algorithm
链栈实现(C语言)
pytest测试框架快速搭建
随机推荐
宏和枚举
具有非矩形布局1结构的电流镜的梯度灵敏度降低
spark常见问题
7-2 rank a linked list (25 points)
树结构
Airtest 进行WebUI自动化测试(selenium)
链栈实现(C语言)
有源和无源设备的共质心布局:回顾和未来之路
1080 graduate admission (30 points)
顺序表的创建插入和修改
[FPGA]: IP Core - - DDR3
Configure your own VIM editor God
【面试:基础篇02:冒泡排序】
Chain stack implementation (C language)
Gradient sensitivity reduction of current mirror with non rectangular layout 1 Structure
JSON output to file line by line in format
Automatic generation of common centroid capacitance array with arbitrary capacitance ratio
Signal noise reduction method
Modify the size of qtcreator interface
1045 favorite color stripe (30 points)