巧用锁 Lock 和 synchronized,让 Java 并发编程得心应手
2023-10-30 14:24:59
Java 并发编程中的锁
在 Java 并发编程中,锁是用来协调多个线程对共享资源的访问,以避免数据不一致或程序崩溃。Java 中的锁主要有两种:Lock 和 synchronized。
Lock
Lock 是 Java 5 引入的新型锁,它提供了比 synchronized 更灵活的锁机制。Lock 接口定义了四种锁操作:
- lock():获取锁。如果锁被其他线程持有,则当前线程将被阻塞,直到锁释放。
- unlock():释放锁。只有持有锁的线程才能释放锁。
- tryLock():尝试获取锁。如果锁被其他线程持有,则当前线程不会被阻塞,而是立即返回 false。
- tryLock(long time, TimeUnit unit):尝试在指定时间内获取锁。如果在指定时间内获取不到锁,则当前线程将被阻塞,直到锁释放或超时。
Lock 接口还定义了一些条件变量,可以用来实现线程之间的等待和通知。
synchronized
synchronized 是 Java 中传统的锁机制。它可以通过修饰方法或代码块来实现。synchronized 修饰的方法或代码块被称为临界区,临界区中的代码只能由一个线程同时执行。
synchronized 的用法非常简单,只需要在需要同步的代码前面加上 synchronized 即可。例如:
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
}
上面的代码中,increment() 方法被 synchronized 修饰,这意味着该方法只能由一个线程同时执行。如果有多个线程同时调用 increment() 方法,那么只有一个线程能够成功执行该方法,其他线程将被阻塞,直到该线程执行完 increment() 方法。
Lock 和 synchronized 的比较
Lock 和 synchronized 都是 Java 中的锁机制,但它们之间还是存在一些差异。
- Lock 提供了更灵活的锁机制,而 synchronized 的用法更简单。
- Lock 可以用来实现线程之间的等待和通知,而 synchronized 不能。
- Lock 可以用来实现公平锁,而 synchronized 不能。
- Lock 的性能通常比 synchronized 更高。
何时使用 Lock 和 synchronized
在实际的并发编程中,应该根据具体情况来选择使用 Lock 或 synchronized。一般来说,如果需要更灵活的锁机制,或者需要实现线程之间的等待和通知,那么可以使用 Lock。如果只需要简单的同步机制,那么可以使用 synchronized。
结语
锁是 Java 并发编程中最重要的同步机制之一。掌握好锁的使用方法,可以有效地避免数据不一致或程序崩溃。Lock 和 synchronized 是 Java 中的两种主要锁机制,它们各有优缺点,应该根据具体情况来选择使用。