目录
参考文章
模拟购票程序
Synchronized锁
Lock锁
公平锁和非公平锁的区别
Lock锁的使用方法
Synchronized锁和Lock锁的区别
参考文章
【狂神说Java】JUC并发编程最新版通俗易懂_哔哩哔哩_bilibili
java中同步锁synchronized与Lock的区别_gm371200587的博客-CSDN博客_java synchronized和lock的区别
模拟购票程序
首先先模拟一个购票的功能
public class Demo01 {
public static void main(String[] args) {
Ticket ticket = new Ticket();
//A线程
new Thread(()->{
for (int i = 0; i < 600; i++) {
ticket.buy();
}
},"A").start();
//B线程
new Thread(()->{
for (int i = 0; i < 600; i++) {
ticket.buy();
}
},"B").start();
//C线程
new Thread(()->{
for (int i = 0; i < 600; i++) {
ticket.buy();
}
},"C").start();
}
//票
static class Ticket{
//总票数
private int totalTicket=500;
//买票
public void buy() {
if (totalTicket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前" + Thread.currentThread().getName() + ":拿到了票,还剩:" + (--totalTicket) + "张票");
}
}
}
}
模拟购票软件,当不加锁的情况下,模拟购票,我们可以看到会出现购票为0的情况,说明并不安全
这就是所谓的并发:多个线程操作同一个资源类,把资源类丢给线程
Synchronized锁
我们可以在起冲突的地方(此处为buy方法)用synchronized修饰,自动加上synchronized锁
这样就不会出现并发错误了
Synchronized锁的本质是排队:队列、锁
Lock锁
主要就是实现Lock接口,Lock接口有三个实现类,分别为
1.ReentrantLock 可重入锁,常用
2.ReadLock 读锁
3.WriteLock 写锁
我们这里先讨论ReentrantLock
我们可以通过上转型方法建立ReentrantLock的对象
private Lock lock = new ReentrantLock();
然后我们进入ReetrantLock的源码,可以看到它的构造方法
我们可以看到有两个构造方法,其中一个是有参构造方法,一个是无参构造方法
其中无参构造方法把锁(Sync)的类型默认设置为非公平锁(NofairSync)
而有参构造方法通过输入的布尔值类型可以判断锁是公平锁(FairSync)和非公平锁(NoFairSync)
这里就要扩展一下公平锁和非公平锁的概念了
公平锁和非公平锁的区别
公平锁:严格按照绝对时间顺序(队列),FIFO(先进先出)
非公平锁:会根据效率自行调整(?)
Lock锁的使用方法
1.先对需要加锁的部分加锁
2.把需要执行的代码块放到try中
3.将unlock放在finally中
也可以解决不安全问题
Synchronized锁和Lock锁的区别
1. synchronized是java内置的关键字,是JVM层面的
Lock是一个java接口
2. synchronized无法获取锁的状态
Lock可以判断是否获得锁
3. synchronized会自动释放锁
Lock需要在finally中手动释放,如果不释放,则会造成死锁
4. 对于synchronized来说,假如有两个线程,线程1和线程2,假如线程1获得锁,但是阻塞了,线程2会一直等待
对于Lock锁来说,不一定会一直等待下去,如果尝试获取不到所,线程可以不用一直等待就结束了(tryLock方法)
5. synchronized可重入锁,是不可以中断的,只能是非公平的
Lock锁也是可重入锁,但是可以判断锁(可以自定义是不是中断?),是否公平可以自己设置
6. synchronized适合锁少量代码的同步问题
Lock适合锁大量的同步代码



