Java Lock 表
1. 引言
在多线程编程中,为了保证共享资源的安全访问,需要使用锁机制来实现线程的互斥和同步。Java提供了许多锁的实现,包括synchronized关键字、ReentrantLock、ReadWriteLock等。本文将对Java中常见的锁进行简要介绍,并给出相关的代码示例。
2. synchronized关键字
synchronized是Java中最基本的锁机制,它是一种独占锁(也称为互斥锁),一次只能有一个线程获取到锁。被synchronized修饰的方法或代码块,在同一时刻只能被一个线程执行。示例代码如下:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
}
上述代码中,increment()
方法被synchronized修饰,保证了多个线程调用该方法时的互斥性。
3. ReentrantLock
ReentrantLock是Java中提供的一个可重入锁实现。可重入锁是指同一个线程可以多次获取同一个锁而不会发生死锁。与synchronized相比,ReentrantLock提供了更灵活的锁操作,如可定时的锁等待、可中断的锁获取等。示例代码如下:
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private int count = 0;
private ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
上述代码中,lock()
方法获取锁,unlock()
方法释放锁。注意在使用ReentrantLock时,需要手动释放锁,否则可能会导致死锁。
4. ReadWriteLock
ReadWriteLock是一种读写锁,它允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这种锁适用于读操作远远多于写操作的场景,可以提高程序的并发性能。示例代码如下:
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private int count = 0;
private ReadWriteLock lock = new ReentrantReadWriteLock();
public void increment() {
lock.writeLock().lock();
try {
count++;
} finally {
lock.writeLock().unlock();
}
}
public int getCount() {
lock.readLock().lock();
try {
return count;
} finally {
lock.readLock().unlock();
}
}
}
上述代码中,writeLock()
方法获取写锁,readLock()
方法获取读锁。在写操作时需要获取写锁,读操作时可以获取读锁。这样可以允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。
5. 比较与选择
在选择锁的时候,需要根据具体的业务场景和需求来选择合适的锁。下表对比了synchronized、ReentrantLock和ReadWriteLock的特点和适用场景:
锁机制 | 特点 | 适用场景 |
---|---|---|
synchronized | - JVM内置支持<br>- 使用简单<br>- 自动释放锁 | - 单线程或低并发场景<br>- 线程间互斥访问共享资源 |
ReentrantLock | - 可重入锁<br>- 提供更灵活的锁操作<br>- 可中断锁 | - 高并发场景<br>- 需要定时锁等待或可中断锁等待的场景 |
ReadWriteLock | - 读写分离<br>- 读操作可以并发执行<br>- 写操作互斥 | - 读操作远远多于写操作的场景<br>- 需要提高程序并发性能的场景 |
6. 总结
本文介绍了Java中常见的锁机制,包括