Synchronized 和 Lock的 区别

124 阅读2分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

同步的基本思想

目的:为了保证共享数据在同一时刻只被一个线程使用,我们有一种很简单的实现思想,就是

1.在共享数据里保存一个锁 ,当没有线程访问时,锁是空的。

2.当有第一个线程访问时,就 在锁里保存这个线程的标识 并允许这个线程访问共享数据。

3.在当前线程释放共享数据之前,如果再有其他线程想要访问共享数据,就要 等待锁释放 。

Synchronized 和 Lock的 区别

1、Synchronized 内置的Java关键字,Lock是一个接口有着众多的实现类

图片.png

2、Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁

Lock类中存在方法
boolean tryLock(); // 尝试获取锁,如果获取成功则证明该锁之前未被占用,如果返回false则证明该锁已被占用

3、Synchronized 会自动释放锁所以被称为隠式锁,lock必须要手动释放锁所以被称为显式锁,如果不释放锁,就会导致死锁

package com.cheng.PC;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@SuppressWarnings({"all"})
class Data03{
    private int num = 10;
    private Lock lock = new ReentrantLock();

    /**
     * 使用Lock(显式锁)
     */
    public void add(){
        try {
            lock.lock(); // 上锁
            if (num < 10){
                num ++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {// 操作结束以后必须执行解锁
            lock.unlock(); // 解锁
        }
    }

    /**
     * 使用synchronized(隠式锁)
     */
    public synchronized void recede(){
         if (num > 0){
             num --;
         }
    }
}

4、使用Synchronized时如果一个线程已经获得了锁,那么其他线程则一定会处于阻塞状态,直到该线程释放锁为止。而使用Lock锁时,因为Lock接口提供了boolean tryLock()方法可以使其它的线程尝试取得锁所以不一定都会处于阻塞状态。

5、因为Synchronized是Java内置关键字所以已经写定了是可重入锁,不可以中断的,非公平锁;而Lock接口存在多个实现类所以可以自己设置相关锁的特性

6、Synchronized 适合少量代码同步问题,Lock 适合锁大量的同步代码

总结:

形象的来说
synchronized(隠式锁)像汽车中的自动档,许多东西都已经帮你设定好了,使用起来方便但是不太灵活
Lock(显式锁)则像手动挡,需要你操作的东西更多但是更加灵活多变,并且在Lock实现类中,也扩展了许多方法可以在你使用的时候更加顺手。