【 java 多线程】同步锁 (Lock) 解决线程的安全问题
📋 个人简介
- 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
- 📝 个人主页:馆主阿牛🔥
- 🎉 支持我:点赞👍+收藏⭐️+留言📝
- 📣 系列专栏:java 小白到高手的蜕变🍁
- 💬格言:要成为光,因为有怕黑的人!🔥
目录
- 📋 个人简介
- 前言
- Lock锁
- 案例
- 面试题:synchronized与Lock的对比
- 开发中实现线程同步的优先使用顺序:
- 结语
前言
我们之前写博文总结了通过同步代码块以及同步方法的方式来实现线程的同步,从而解决线程的安全问题,今天我总结一下Lock锁来实现线程的同步!
Lock锁
-
从 JDK 5.0开始, Java 就提供了更强大的线程同步机制:通过显式定义同
步锁对象来实现同步。同步锁使用 Lock 对象充当。 -
java.util.concurrent.locks.Lock 接口是控制多个线程对共享资源进行访问的
工具。锁提供了对共享资源的独占访问,每次只能有一个线程对 Lock 对象加锁,线程开始访问共享资源之前应先获得 Lock 对象。 -
ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是 ReentrantLock ,可以显式加锁、释放锁。
案例
我们依旧使用多窗口卖票这个经典案例。用Lock锁实现同步,解决重票错票问题。
package lock锁;
import java.util.concurrent.locks.ReentrantLock;
public class Demo {
public static void main(String[] args) {
MyTh m = new MyTh();
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
Thread t3 = new Thread(m);
t1.setName("窗口一");
t2.setName("窗口二");
t3.setName("窗口三");
t1.start();
t2.start();
t3.start();
}
}
class MyTh implements Runnable{
private int tickets = 100;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
lock.lock(); // 调用lock()方法加锁
try {
if(tickets>0){
System.out.println(Thread.currentThread().getName() + "-票号为:" + tickets);
tickets--;
}else{
break;
}
}finally {
lock.unlock(); // 调用unlock()方法解锁
}
}
}
}
面试题:synchronized与Lock的对比
- Lock 是显式锁(手动开启和关闭锁,别忘记关闭锁), synchronized 是隐式锁,出了作用域自动释放。
- Lock 只有代码块锁, synchronized 有代码块锁和方法锁。
- 使用 Lock 锁, JVM 将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)。
开发中实现线程同步的优先使用顺序:
Lock→同步代码块→ 同步方法
结语
如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。
🏰系列专栏
👉软磨 css
👉硬泡 javascript
👉flask框架快速入门