Java 并发编程中的 java.util.concurrent
(简称 JUC)包提供了多种高级并发工具,其中包括独占共享锁(读写锁)和 ReentrantReadWriteLock
等类。下面将详细介绍这些概念。
独占共享锁(Read-Write Locks)
独占共享锁也称为读写锁,它允许多个读操作同时进行,但只允许一个写操作进行。读写锁非常适合那些读操作远多于写操作的场景,因为在读写锁中,读操作可以并发执行,从而显著提高程序的性能。
读写锁的特点
- 读-读共享:多个读线程可以同时访问共享资源。
- 读-写互斥:读操作和写操作不能同时进行。
- 写-写互斥:多个写操作也不能同时进行。
ReentrantReadWriteLock
ReentrantReadWriteLock
是 JUC 包中提供的一个实现了读写锁的类。它支持重入,即一个已经拥有读锁或写锁的线程可以再次获取同一个锁。
示例
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
private String data;
public void readData() {
readLock.lock();
try {
System.out.println(Thread.currentThread().getName() + " is reading data: " + data);
} finally {
readLock.unlock();
}
}
public void writeData(String newData) {
writeLock.lock();
try {
data = newData;
System.out.println(Thread.currentThread().getName() + " has written data: " + data);
} finally {
writeLock.unlock();
}
}
}
在这个示例中,我们创建了一个 ReentrantReadWriteLock
实例,并从中获取了读锁和写锁。readData
方法用于读取数据,而 writeData
方法用于写入数据。
LockSupport
LockSupport
是 java.util.concurrent.locks
包中的一个类,它提供了一组工具方法来支持高级的线程阻塞和唤醒操作。LockSupport
的核心功能在于它提供了一种机制,使得一个线程能够阻塞另一个线程,而不需要显式地获取和释放锁。
LockSupport 的主要方法
- park():使当前线程进入等待状态,直到被另一个线程唤醒。
- unpark(Thread thread):唤醒一个被 park 的线程。
- parkNanos(long nanos):使当前线程进入等待状态,直到被另一个线程唤醒或等待了指定的纳秒时间。
- parkUntil(long deadlineTime):使当前线程进入等待状态,直到被另一个线程唤醒或到达指定的截止时间。
示例
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
public class LockSupportExample {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
System.out.println("Thread T1 is waiting to be unparked...");
LockSupport.park();
System.out.println("Thread T1 has been unparked.");
}, "T1");
t1.start();
TimeUnit.SECONDS.sleep(1); // 等待一段时间
// 唤醒线程 T1
LockSupport.unpark(t1);
}
}
在这个示例中,线程 T1
使用 LockSupport.park()
进入等待状态,然后主线程使用 LockSupport.unpark(t1)
来唤醒 T1
。
总结
ReentrantReadWriteLock
和 LockSupport
是 Java 并发编程中非常有用的工具。ReentrantReadWriteLock
提供了一种灵活的方式来实现读写锁,可以提高多线程程序的并发性能。而 LockSupport
则提供了一种简单的线程阻塞和唤醒机制,可以在不需要显式锁的情况下实现线程间的协作。
在实际开发中,选择使用这些工具取决于具体的应用场景。如果需要实现更高级别的锁机制或者更细粒度的线程控制,ReentrantReadWriteLock
和 LockSupport
都是非常好的选择。