首页 > 编程笔记 > Java笔记 阅读:1

Java读锁和写锁的用法(附带实例)

读锁和写锁是控制多线程环境中对共享资源访问的两种锁机制,主要区别体现在它们对并发访问的管理上。

读锁允许多个线程同时获取锁进行读取操作,不允许任何写入操作发生,因此,当读锁存在时,可以保证读取操作的并发性和效率。在读多写少的场景中,使用读锁可以提高性能,多个线程可以并行读取,不会发生冲突。

而写锁一次只允许一个线程获取锁进行写入操作,在写锁被持有时,其他线程的读取或写入操作会被阻塞,从而保证写入操作对共享资源的独占访问。在写入操作频繁的场景下,写锁确保了写入操作的安全性,防止了写入时数据的不一致性。

读锁和写锁的主要区别可以总结为以下几点:
在 Java 中,ReadWriteLock 接口有一个实现类 ReentrantReadWriteLock,它集成了读锁和写锁的功能,保证了当有写锁被持有时,其他线程既不能获取读锁也不能获取写锁;而当没有写锁被持有时,多个线程可以同时获取读锁。

下面我们通过一个 Java 代码示例,演示如何使用 ReentrantReadWriteLock 的读锁和写锁来保护一个共享数据结构,在多线程环境中进行安全的并发读取和写入操作。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SharedDataStructure {
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private int sharedValue = 0; //共享资源
    // 读取共享数据的方法
    public void readSharedValue() {
        // 尝试获取读锁
        readWriteLock.readLock().lock();
        try {
            // 在这里模拟读取操作
            System.out.println(Thread.currentThread().getName() + " Reading value: " + sharedValue);
            // 实际的读取代码将放在这里
        } finally {
            // 确保在读取完毕后释放读锁
            readWriteLock.readLock().unlock();
        }
    }
    // 写入共享数据的方法
    public void writeSharedValue(int newValue) {
        // 尝试获取写锁
        readWriteLock.writeLock().lock();
        try {
            // 在这里模拟写入操作
            sharedValue = newValue;
            System.out.println(Thread.currentThread().getName() + " Writing value: " + newValue);
            // 实际的写入代码将放在这里
        } finally {
            // 确保在写入完毕后释放写锁
            readWriteLock.writeLock().unlock();
        }
    }
    public static void main(String[] args) {
        SharedDataStructure sharedData = new SharedDataStructure();
        // 创建并启动5个读线程
        for (int i = 0; i < 5; i++) {
            new Thread(() -> sharedData.readSharedValue(), "Reader-" + i).start();
        }
        // 创建并启动1个写线程
        new Thread(() -> sharedData.writeSharedValue(100), "Writer").start();
    }
}
在上述示例中,SharedDataStructure 类中有一个 ReadWriteLock 能够保护共享资源 sharedValue。当线程调用 readSharedValue() 方法时,它获取读锁,在执行读取操作期间,其他线程可以获取读锁来执行它们的读取操作。一旦读取操作完成,线程会释放读锁。

在 main() 方法中创建并启动了 5 个读线程和 1 个写线程,读线程并发地读取值,而写线程尝试修改这个值。由 ReentrantReadWriteLock 的特性可知,多个读线程可以同时读取数据,但写线程在执行写入操作时会阻塞所有读取和写入操作,直到它完成写入并释放写锁。

在实际的数据库系统、文件系统或并发编程中,读锁和写锁的应用是保障数据一致性和提高并发性能的重要工具。

相关文章