1.ReentrantLock与synchronize
相同点:
- 都是用于线程同步锁,都是互斥锁。
不同点:
- 如果用汽车来类比,synchronize相当于自动挡,Lock相当于手动挡。即:synchronize是内置锁,只要加上synchronize的代码的地方开始,代码结束的地方自动释放资源。lock必须手动加锁,手动释放资源。
- synchronize优点是代码量少,自动化。缺点是扩展性低,不够灵活。
- Lock优点是扩展性好,灵活。缺点是代码量相对稍多。
- 释放锁的情况:
- synchronize:1)线程执行完毕;2)线程发生异常;3)线程进入休眠状态。
- Lock:通过unLock()方法。
注意点:
- wait()和notify()/notifyAll()必须出现在synchronize修饰的代码块中;
- 资源的释放通常放在finally中;
- 最好不要将lock()方法写在try{}中,因为如果 发生异常的话,抛出异常,同时锁资源无法释放。
2.ReentrantLock与ReentrantReadWriteLock
ReentrantLock:
- 俗称重入锁,实现了Lock接口
- 是一种完全互斥锁,即某一时刻永远只允许一个线程访问共享资源,不管是读数据的线程还是写数据的线程。这导致的结果就是,效率低下。
- 通过newCondition的await与signal代替wait与notify
ReentrantReadWriteLock:
- 俗称读写锁(共享锁,排他锁)。实现了ReadWriteLock接口
- 允许线程同时读取共享资源;但是如果有一个线程是写数据,那么其他线程就不能去读写该资源(除了写的那个线程,其他全部阻塞)。
- 三种情况:读读共享,写写互斥,读写互斥。