synchronized
和 Lock
都是Java中用于实现线程同步的手段,它们有以下主要区别:
synchronized(同步关键字)
- 内置锁:
synchronized
是Java的一个关键字,它是一个内置锁,由JVM自动管理。 - 使用方便:使用
synchronized
,你只需要在方法声明或代码块前加上synchronized
关键字即可。 - 不可中断方法:当一个线程执行
synchronized
方法或块时,其他线程必须等待直到该线程退出同步代码块。 - 悲观锁:
synchronized
是一种悲观锁,它假设冲突发生的可能性较大,因此它会直接上锁。 - 锁状态不可改变:
synchronized
锁定后,无法改变锁状态,它要么锁定,要么不锁定。 - 公平性:
synchronized
不支持公平性设置,即等待时间最长的线程并不一定会最先获得锁。 - 功能限制:
synchronized
只提供了基本的同步功能,没有高级功能,如尝试非阻塞地获取锁、超时等待等。
Lock(锁对象)
- 显示锁:
Lock
是Javajava.util.concurrent.locks
包中的一个接口,它是一个显示锁,需要程序员手动管理。 - 灵活性高:
Lock
提供了更复杂的线程控制,例如,可以尝试非阻塞地获取锁、可以响应中断、可指定公平性等。 - 可中断:执行
Lock
的线程可以响应中断,即在等待获取锁的过程中可以中断等待。 - 公平性:
Lock
可以实现公平性,即等待时间最长的线程可以最先获得锁(通过ReentrantLock
的构造函数设置)。 - 多种锁模式:
Lock
提供了多种锁模式,如读写锁(ReadWriteLock
)。 - 悲观/乐观锁:
Lock
可以实现悲观锁和乐观锁,例如,ReentrantLock
是悲观锁,而StampedLock
是乐观锁。 - 高级功能:
Lock
提供了更多的高级功能,如尝试获取锁、超时获取锁、尝试获取锁后响应中断等。
示例
java">// 使用 synchronized
public synchronized void synchronizedMethod() {// 同步代码
}// 使用 Lock
Lock lock = new ReentrantLock();
public void lockMethod() {lock.lock(); // 获取锁try {// 同步代码} finally {lock.unlock(); // 释放锁}
}
总结
synchronized
和 Lock
都可以用于线程同步,但它们在用法和功能上有所不同。synchronized
是一种内置锁,使用简单,但功能有限。Lock
是一个显示锁,提供了更多的控制和灵活性,适用于需要高级同步功能的场景。在实际编程中,根据具体需求选择合适的同步机制是非常重要的。