在 Java 中,锁是一种多线程同步机制,可以保证在同一时间只有一个线程可以访问共享资源。Java 中提供了多种锁,常见的锁有以下几种:
1.synchronized 关键字
synchronized 是一种最基本的锁机制,可以用来保证方法或代码块在同一时刻只能被一个线程执行。synchronized 可以加在方法上,也可以用来包裹一段代码块。
使用示例:
public synchronized void method() {
// synchronized 修饰方法
}
public void method2() {
synchronized (this) {
// synchronized 修饰代码块
}
}
2.ReentrantLock
ReentrantLock 是一种可重入的锁,它可以替代 synchronized 来达到同样的效果,但比 synchronized 更强大。ReentrantLock 可以实现公平锁和非公平锁,使用时需要注意。
使用示例:
ReentrantLock lock = new ReentrantLock();
public void method() {
lock.lock(); // 加锁
try {
// 执行代码
} finally {
lock.unlock(); // 解锁
}
}
3.ReadWriteLock
ReadWriteLock 是一种读写锁,它允许多个线程同时对共享资源进行读操作,但只允许一个线程进行写操作。可以用来提高读操作的并发性。
使用示例:
ReadWriteLock lock = new ReentrantReadWriteLock();
public void readMethod() {
lock.readLock().lock(); // 获取读锁
try {
// 执行读操作
} finally {
lock.readLock().unlock(); // 释放读锁
}
}
public void writeMethod() {
lock.writeLock().lock(); // 获取写锁
try {
// 执行写操作
} finally {
lock.writeLock().unlock(); // 释放写锁
}
}
4.StampedLock
StampedLock 是一种乐观锁,它通过判断资源版本号来实现乐观锁机制,能够提高读操作的并发性。StampedLock 支持三种模式:读模式、写模式和乐观读模式,使用时需要注意。
使用示例:
StampedLock lock = new StampedLock();
public void readMethod() {
long stamp = lock.tryOptimisticRead(); // 尝试获取乐观读锁
// 执行读操作
if (!lock.validate(stamp)) { // 校验版本号
stamp = lock.readLock(); // 获取正式读锁
try {
// 重新执行读操作
} finally {
lock.unlockRead(stamp); // 释放读锁
}
}
}
public void writeMethod() {
long stamp = lock.writeLock(); // 获取写锁
try {
// 执行写操作
} finally {
lock.unlockWrite(stamp); // 释放写锁
}
}
5.Semaphore
Semaphore 是一种信号量机制,它可以控制同时访问共享资源的线程数。Semaphore 可以用于限流等场景。
使用示例:
Semaphore semaphore = new Semaphore(10); // 控制同时访问共享资源的线程数为 10
public void method() {
try {
semaphore.acquire(); // 获取信号量
// 执行代码
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 释放信号量
}
}
以上是 Java 中常用的锁机制介绍及使用示例,使用时需要根据具体场景选择合适的锁机制,避免死锁等问题。