这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」
lock与sychroinzed的区别
1.类型
sychronized 是java 关键字
Lock是一个类
2.获取锁的状态
synchornized无法获取锁的状态
Lock 可以判断是否获取到了锁。
2.阻塞情况
sychronized 在线程阻塞的状态下,A加锁,B会一直等待
Lock在A阻塞的情况下会B尝试去获得锁,线程不会一直等待
3.释放锁
sychronized 在执行完同步代码后,会释放锁。出现异常,jvm会释放锁 。
Lock在finally中必须释放锁,否则可能会引起死锁。Lock在发生异常时不会释放锁,所以需要try,catch,并且在finally中unlock
4.中断
sychronized不能被中断,只能等待锁的释放,可重入锁,可公平(lock(true))
Lock 在等待锁的过程中可以被interrupt中断等待,可重入锁,非公平的
5.性能
Lock可以使用读写锁readwritelock 实现读写分离,提高多线程的效率。因此在竞争激烈的情况下,Lock的性能远远大于sychornized。设和大量并发的情况下
6.用法
sychornized: 对象可以当作锁,可以加载需要加锁的代码块中,方法中。
Lock: 使用ReentrantLock 作为锁,在加锁和解锁时使用lock()和unlock() 。一般会在finally中增加unlock()以防死锁的情况发生。
7.实现原理
悲观锁:一种对数据的修改持有悲观态度的并发控制方式。总是假设最坏的情况,每次读取数据的时候都默认其他线程会更改数据,因此需要进行加锁操作,当其他线程想要访问数据时,都需要阻塞挂起.可以分为共享锁和排他锁 。因此悲观锁的效率低
共享锁:多个事务可以共享一把锁,但是只能读,不能修改
排他锁:顾名思义,一个事务获得,其他事务就不能获得,但是可以修改
乐观锁:对数据修改持有乐观态度,假设数据一般情况下不会产生冲突,只有在数据修改提交的情况下才会检查是否冲突。如果冲突了,就给用户返回信息,让用户自己选择。 因此可以提高性能
一般使用CAS或者数据库版本号解决冲突
8.特殊情境
当一个线程在等待锁的控制需要中断他的等待时,LOCK可以打断他。
每个线程都公平竞争,Lock有公平锁
Lock可以选择公平锁和非公平锁(默认,可以插队)