Java并发编程之重入锁与读写锁
什么是锁
在多线程编程中,为了保证多线程之间数据的一致性和正确性,我们常常需要对共享数据进行加锁处理,以避免出现竞态条件(Race condition)导致的数据错误或程序崩溃等问题。锁是一个非常重要的多线程并发编程工具。
Lock接口
在Java中,锁的实现是通过java.util.concurrent.locks
包中的Lock
接口。
Lock
接口中定义了三个API:
lock()
: 获取锁,并且如果锁被占用就一直等待。tryLock()
: 尝试获取锁,如果锁没有被占用就获取并返回true
;如果锁已经被占用就返回false
,不会等待。unlock()
: 释放锁。
重入锁
重入锁(Reentrant Lock)是Java并发编程中最常用的一种锁,它支持重进入的特性。什么是重进入呢?指的是当一个线程获取到锁之后,可以多次获取锁,而不会被阻塞。这在某些场合下是非常方便的。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
new Thread(() -> {
lock.lock();
System.out.println("Thread 1 holding lock");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
System.out.println("Thread 1 releasing lock");
}).start();
new Thread(() -> {
lock.lock();
System.out.println("Thread 2 holding lock");
lock.unlock();
System.out.println("Thread 2 releasing lock");
}).start();
}
}
在上面的代码中,我们创建了两个线程,分别获取了同一把重入锁。当第一个线程获取锁之后,睡眠1秒钟,然后释放锁;第二个线程获取锁之后,直接释放锁。运行这段代码,可以看到输出结果如下:
Thread 1 holding lock
Thread 1 releasing lock
Thread 2 holding lock
Thread 2 releasing lock
读写锁
读写锁(ReadWrite Lock)是一种特殊的重入锁,它允许多个读线程同时访问共享资源,但是只允许一个写线程访问共享资源。读写锁的实现通常有两种:
- 读写锁中仅包含读锁和写锁;
- 读写锁中包含读锁、写锁以及快速锁(Fast Lock)。
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockDemo {
private static final ReadWriteLock lock = new ReentrantReadWriteLock();
private static int value = 0;
public static void main(String[] args) {
new Thread(() -> write()).start();
new Thread(() -> read()).start();
new Thread(() -> read()).start();
}
private static void read() {
lock.readLock().lock();
System.out.println("Reading value: " + value);
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finish reading value: " + value);
lock.readLock().unlock();
}
private static void write() {
lock.writeLock().lock();
System.out.println("Writing value: " + ++value);
lock.writeLock().unlock();
}
}
在上面的代码中,我们创建了一个读写锁,并且创建了一个value
变量用于测试。我们启动了三个线程:一个写线程和两个读线程。当写线程获取锁之后,增加value
的值。当读线程获取锁之后,打印value
的值,然后睡眠随机时间。运行这段代码,可以看到输出结果如下:
Writing value: 1
Reading value: 1
Reading value: 1
Finish reading value: 1
Finish reading value: 1
从输出结果中,可以看到读写锁确实允许多个读线程同时访问共享资源,而当一个线程获取写锁之后,其它线程无法访问共享资源,直到释放写锁。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发编程之重入锁与读写锁 - Python技术站