Java有了synchronized,为什么还要提供Lock?
1、可中断性
Lock接口提供了可中断的获取锁的方法,例如lockInterruptibly()。当一个线程在等待锁的过程中,可以被其他线程中断,这样可以更灵活地处理线程的中断请求。而synchronized关键字在等待锁时,线程是不可中断的,只有等待获取锁的线程结束或者获取锁后释放锁,其他线程才能参与竞争。
2、超时获取
Lock接口允许线程在指定的时间范围内尝试获取锁,如果在指定时间内未能成功获取锁,线程可以根据实际情况做出相应处理。这个特性在一些场景下非常有用,而synchronized关键字没有直接支持这种超时获取的功能。
3、公平性
Lock接口可以实现公平锁,即按照线程等待的顺序来获取锁,避免某些线程长时间等待而导致饥饿的问题。而synchronized关键字并没有提供公平锁的机制,导致某些线程可能一直无法获取到锁。
4、多条件变量
Lock接口允许创建多个Condition对象,每个Condition对象可以管理一个线程等待队列,并且可以通过await()和signal()等方法来控制线程的等待和唤醒。这在复杂的线程同步场景中非常有用。而synchronized关键字只支持一个内置条件变量,使用起来相对有限。
5、可重入性
Lock接口支持可重入锁,即同一个线程可以多次获取同一个锁,而不会被阻塞。这对于递归调用或者某些特殊情况下非常有用。synchronized关键字也是可重入的,但在某些情况下可能会引起死锁问题。
6、性能和扩展性
在一些高并发的场景中,Lock接口相比synchronized关键字在性能上可能有一定的优势,尤其是对于细粒度的锁控制。而且,Java提供的Lock接口有多个实现类,例如ReentrantLock、StampedLock等,开发者可以根据具体的需求选择合适的实现,而synchronized关键字只有一种内置锁。
延伸阅读
synchronized是什么
synchronized是Java中的一个关键字,用于实现线程的同步和互斥。它可以应用在方法、代码块或静态方法上,用于确保在多线程环境下共享资源的安全访问。当一个方法或代码块被synchronized修饰时,它就变成了一个临界区(critical section),同一时刻只有一个线程可以进入这个临界区执行代码,其他线程需要等待。这样可以避免多个线程同时访问共享资源而导致的数据不一致或竞态条件问题。