先看官方文档:
实现类有可重入锁、读锁和写锁,可重入锁最常用。
可重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。
可以看到,ReentrantLock是lock接口的一个实现类,里面实现了可重入锁和公平锁非公平锁。
公平锁:十分的公平,先来后到。
非公平锁:十分不公平,可以插队。
默认实现的是非公平锁。
它的整个逻辑就是:加锁,在try里写业务代码,在finally里解锁。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author DB
* @title: Test02
* @projectName Juc
* @description: TODO
* @date 2022/4/21 10:34
*/
public class Test02 {
public static void main(String[] args) {
Ticket2 ticket2 = new Ticket2();
new Thread(() -> { for (int i = 0; i < 40; i ++)ticket2.sale();}, "A").start();
new Thread(() -> { for (int i = 0; i < 40; i ++)ticket2.sale();}, "B").start();
new Thread(() -> { for (int i = 0; i < 40; i ++)ticket2.sale();}, "C").start();
}
}
class Ticket2 {
//属性
private int number = 30;
Lock lock = new ReentrantLock();
//方法
public synchronized void sale(){
//加锁
lock.lock();
try {
//写业务代码
if (number > 0){
System.out.println(Thread.currentThread().getName() + "卖出了" + (number --) + "票,剩余" + number);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//解锁
lock.unlock();
}
}
}
结果:
Synchronized和Lock的区别?
(1)Synchronized 是Java的内置关键字;Lock是一个Java类。
(2)Synchronized 无法判断获取锁的状态;Lock可以判断是否获取到了锁。
(3)Synchronized 会自动释放锁;lock必须手动释放锁,如果不释放->死锁。
(4)Synchronized 线程1(获得锁,阻塞),线程2(等待,傻傻的等);lock锁不一定会等。
(5)Synchronized 可重入锁,不可以中断的,非公平锁;Lock锁,可重入锁,可以判断,自己可以设置公平还是非公平。
(6)Synchronized 适合锁少量的代码同步问题;Lock适合锁大量的同步代码。