7.Lock 同步锁
Lock( 锁 )
-
从
JDK 5.0
开始,Java
提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock
对象充当。 -
java.util.concurrent.locks.Lock
接口 是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock
对象加锁,线程开始访问共享资源之前应先获得Lock
对象。 -
ReentrantLock
类 是实现了Lock
接口的一个实现类 ,它拥有与synchronized
相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock
类,可以显式加锁、释放锁。
显示锁 Lock
- 在 Java 5.0 之前,协调共享对象的访问时可以使用的机制只有 synchronized 和 volatile 。Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。
- ReentrantLock 实现了 Lock 接口,并提供了与 synchronized 相同的互斥性和内存可见性。但相较于 synchronized 提供了更高的处理锁的灵活性。
Lock(锁)示例
import java.util.concurrent.locks.ReentrantLock;
class A{
private final ReentrantLock lock = new ReentrantLock(); // 创建锁
public void m(){
lock.lock();
try{
//保证线程安全的代码; }
finally{
lock.unlock();
}
}
}
// 注意:如果同步代码有异常,要将unlock()写入finally语句块
下面再写一个将前面账号取款的线程安全问题的示例。
线程安全问题的示例 – 多线程窗口卖票
1.首先创建一个售票的线程类
//创建线程类: 售卖车票
class Ticket implements Runnable {
//成员属性
private int tick = 100;
//重写run
@Override
public void run() {
//循环卖票,直到票卖完
while (true) {
//存在有票,继续售卖
if (tick > 0) {
//休眠500毫秒
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卖票
tick--;
//打印当前的票数
System.out.println(Thread.currentThread().getName() + " 剩余票:" + tick);
} else {
break;
}
}
}
}
2.创建三个线程,同时售票,演示线程安全问题
public class TestLock {
public static void main(String[] args) {
//创建线程类对象
Ticket ticket = new Ticket();
//创建三个线程
new Thread(ticket, "1号窗口").start();
new Thread(ticket, "2号窗口").start();
new Thread(ticket, "3号窗口").start();
}
}
测试执行如下:
使用 Lock 解决线程安全问题
1.在售票的线程类创建 Lock,并且设置上锁以及释放锁
//创建线程类: 售卖车票
class Ticket implements Runnable {
//成员属性
private int tick = 100;
//创建 lock 锁
private final ReentrantLock lock = new ReentrantLock();
//重写run
@Override
public void run() {
//循环卖票,直到票卖完
while (true) {
lock.lock(); // 上锁
//存在有票,继续售卖
try {
if (tick > 0) {
//休眠500毫秒
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卖票
tick--;
//打印当前的票数
System.out.println(Thread.currentThread().getName() + " 剩余票:" + tick);
}
} finally {
lock.unlock(); // 在finally释放锁
}
}
}
}
2.再次测试执行如下
可以看到已经逐个执行了,没有出现重复值。
原文始发于微信公众号(海洋的渔夫):7.Lock 同步锁
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/34979.html