Java 并发中的 Lock 框架与线程同步

2024年9月10日 | 阅读 6 分钟

Lock 框架

在 Java 中,Lock 框架线程同步机制用于管理对共享资源的并发访问,并确保多线程应用程序中的线程安全。

它是一组类和接口,存在于 java.util.concurrent 包中。它提供了一种灵活高效的方式来同步对共享资源的访问。它还提供了许多具体的锁实现。最常见的具体锁实现是 ReentrantLock 和 ReadWriteLock。

ReentrantLock 类是 Java 中一种允许线程多次获取锁而不会阻塞自身的锁类型。它是一个可重入锁,并提供了公平或不公平获取锁的方法。

ReadWriteLock 类提供了一种机制,允许多个线程同时读取共享资源,同时确保在任何给定时间只有一个线程可以写入该资源。

Lock 框架是一个强大的工具,它在多线程应用程序中调节对共享资源的访问,通过防止冲突并确保有序执行来提高性能和可扩展性。

以下是如何使用 Lock 框架的示例。

LockExample.java

输出

Thread-1 incremented counter to 1
Thread-0 incremented counter to 2
Thread-1 incremented counter to 3
Thread-0 incremented counter to 4

线程同步

Java 中的线程同步是一种机制,它确保多个线程能够以互斥的方式访问共享资源或执行操作。它防止线程相互干扰,从而导致数据不一致或竞态条件。

在 Java 中实现线程同步的方法有以下几种:

1. Synchronized 方法:通过将方法声明为 synchronized,一次只有一个线程可以执行该方法。其他尝试访问 synchronized 方法的线程将被阻塞,直到执行线程完成其执行。

SynchronizedMethodExample.java

输出

Thread Thread 1 - Step 1Thread Thread 1 - Step 2
Thread Thread 1 - Step 3
Thread Thread 1 - Step 4
Thread Thread 1 - Step 5
Thread Thread 2 - Step 1Thread Thread 2 - Step 2
Thread Thread 2 - Step 3
Thread Thread 2 - Step 4
Thread Thread 2 - Step 5

2. Synchronized 块:与其同步整个方法,不如使用 synchronized 关键字同步特定的代码块。它允许对需要同步的代码部分进行更细粒度的控制。

3. ReentrantLock:更灵活的线程同步。允许多个线程以受控的方式获取和释放锁。

ReentrantLockExample.java

输出

Thread 1: Lock acquired
Thread 1: Lock released
Thread 2: Lock acquired
Thread 2: Lock released

4.信号量 (semaphore)是一种变量或抽象数据类型,它限制了可以访问共享资源的线程数量。在并发系统中,如多任务操作系统,信号量用于控制多个线程对公共资源的访问。

ShortSemaphoreExample.java

输出

Thread 1 is waiting to acquire a permit.
Thread 2 is waiting to acquire a permit.
Thread 1 has acquired a permit and is working.
Thread 1 has finished working and is releasing the permit.
Thread 2 has acquired a permit and is working.
Thread 2 has finished working and is releasing the permit.

Java 中的 Lock 框架与线程同步的区别

Lock 框架线程同步
Java 5 中引入自 Java 早期版本起可用
提供增强的灵活性和对锁定机制的精确控制。提供一种更简单、更直接的同步方法。
支持多条件和公平性。仅支持基本同步。
允许非阻塞和带超时的锁获取。允许阻塞锁获取。
允许以任何顺序获取和释放多个锁。需要按特定顺序获取和释放锁。
在高竞争场景下提供更好的性能。在高竞争场景下可能存在性能开销。
使用和理解起来可能更复杂。使用和理解起来更简单。
需要显式获取和释放锁。自动获取和释放锁。
支持 ReentrantLock、ReentrantReadWriteLock 等。支持 synchronized 关键字、wait()、notify()、notifyAll() 方法。

总而言之,Java 中的 Lock 框架和线程同步对于维护线程安全和防止多线程应用程序中的竞态条件至关重要。它们有助于确保对共享资源的并发访问得到正确同步,从而实现正确且可预测的程序行为。