Java中的锁机制
在学习Java的并发编程中, 锁机制是一个重点和难点, 在Java中并发常用到的锁相关的主要是synchronized
关键字和java.util.concurrent.locks
类, 两者的区别包括
synchronized
是关键字, 依赖JVM实现锁机制,Lock
是JDK中的一个接口, 其实现最典型的是ReentrantLock
类synchronized
的实现是编译期加入了管程的机制,ReentrantLock
的实现是依赖底层的AbstractQueuedSynchronizer
(AQS), 而AQS
又使用到了Java中的CAS
机制.synchronized
不需要手动释放, 在临界区的代码出现异常时, 也能够正确的进行自动解锁.Lock
的实现类需要手动上锁和解锁, 为了保证代码出现异常时能够释放锁, 需要将代码段包在try-finally
语句中Lock
实现类比synchonized
更加灵活, 支持tryLock
方法能够设置超时时间, 也可以控制被阻塞的线程是否能够相应中断,synchonized
不行Lock
的实现类中读写锁可以提高读操作效率, 实现类也能够知道是否获得了锁- 在竞争不激烈时, 两者相差不大, 竞争激烈的情况下,
Lock
性能远优于synchonized
synchronized
是可重入锁synchronized
不可中断,Lock
可中断
说了怎么多, 不如动手写点代码, 从代码中了解并发编程中应该如何用锁, 以及一个锁大致是怎么实现.
一个并发操作的Demo
import java.util.LinkedList;
import java.util.List;
public class TestConcurrent {
public static void main(String[] args) throws InterruptedException {
Share share = new Share();
List<Thread> tList = new LinkedList<>();
for (int i = 0; i < 5; i++) {
Thread t = new Thread(
()-> {