类别 | synchronized | Lock |
---|---|---|
存在层次 | Java的关键字,在jvm层面上 | 是一个类 |
锁的获取 | 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 | lock():获取锁,如果锁被占用则一直等待; tryLock(): 立即返回true(获取锁成功),false(锁被占用,获取锁失败); tryLock(long time, TimeUnit unit):如果锁未被占用,立即返回true(获取锁成功),如果锁被占用,则最多等待time。 lockInterruptibly():可中断的获取锁,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事 |
锁的释放 | 1、以获取锁的线程执行完同步代码,释放锁。 2、线程执行发生异常,jvm会让线程释放锁 | 必须在finally中必须释放锁,不然容易造成线程死锁 |
锁状态 | 无法判断 | 可以判断 |
锁类型 | 可重入(re-entrant) 不可中断 非公平 悲观锁 |
可重入(re-entrant) 可中断 可公平(两者皆可) 乐观锁(底层主要靠volatile和CAS操作实现的) |
性能 | 少量竞争时性能好 | 竞争激烈时性能好 |
可重入锁:1. 加锁方法调用另外一个加锁方法; 2. 递归调用加锁方法;
独享锁:该锁每一次只能被一个线程所持有,其他线程等待。
共享锁:该锁可被多个线程共有。
ReentrantLock是独享锁。
ReentrantReadWriteLock里的读锁是可以被共享的,但是它的写锁确每次只能被独占。
读锁的共享可保证并发读是非常高效的,但是读写和写写,写读都是互斥的。