> 文章列表 > lock与synchronized锁有什么区别?它们的底层实现原理是什么?

lock与synchronized锁有什么区别?它们的底层实现原理是什么?

lock与synchronized锁有什么区别?它们的底层实现原理是什么?

一、共同点

        Lock和synchronized都是本地锁,它们都可以通过上锁解决多个线程访问共享资源的问题,并且synchronized和lock锁都支持可重入锁机制,即同一个线程在已经获得锁的情况下能够再次获取该锁

二、区别

(一)、synchronized只有一种锁类型就是独占锁,Lock 提供了更多的锁机制选择,例如公平锁、非公平锁,读写锁等

(二)、lock合适在高并发场景下使用,而synchronized适合在简单场景下使用

(三)、synchronized是关键字,源码在jvm中,用c++ 语言实现。Lock 是接口,源码由jdk 提供,用java语言实现

(四)、synchronized退出同步代码块jvm会自动释放锁,Lock不会自动释放锁,需要调用unlock方法手动释放锁,不然可能会造成死锁问题。

5、synchronized锁是悲观锁,lock是乐观锁
 

三、synchronized原理

        首先synchronized普通同步方法,锁是当前实例对象;静态同步方法,锁是当前类的 class 对象;同步方法块,锁是括号里面的对象。

(一)、synchronized保证了共享变量可见性和原子性,共享变量可见性是通过JVM底层的内存屏障来实现的,原子性则是通过监视器锁的互斥性来实现的。
(二)、在synchronized内线程获得了锁,它将会清空工作内存,从而使得该线程使用的变量能够从主内存中重新读取,同时也会把工作内存中的变量写回到主内存中。这样,其他线程就可以读取到最新的值,从而保证了可见性。

四、lock锁的原理

(一)、lock是一个接口,实际开发中我们经常用它的是实现类来上锁。

      ReentrantLock lock = new ReentrantLock();  // 创建一个 ReentrantLock 对象// 加锁lock.lock();try {// 被锁住的代码块} finally {// 释放锁lock.unlock();}

(二)、CAS算法实现上锁和解锁

1、lock锁是通过CAS乐观锁算法实现的,当一个线程调用lock()方法时,它会尝试获取锁,该方法会使用CAS操作(原子性)来尝试获取锁。

2、如果当前锁没有被其他线程占用,那么这个线程就会获取锁,并成为锁的持有者;

3、当其他线程尝试获取锁时,但因为锁已经被持有者持有,所以它们会一直尝试获取锁直到锁被释放。

4、当持有锁的线程调用unlock()方法时,它会释放锁并成为锁的持有者;

5、当其他线程尝试获取锁时,它们会被放入等待队列中,并且当锁被释放时,等待队列中的线程会被通知来获取锁。