什么是Java锁?
Java锁是一种同步机制,可以用于协调并发访问共享资源。Java中的锁可以分为两类:
- 互斥锁(Mutex Lock):一次只能有一个线程持有锁,其他线程必须等待当前线程释放锁之后才能获得锁。
- 共享锁(Read-Write Lock):多个线程可以同时持有共享锁,但是不能同时持有独占锁。
Java中提供了多种锁的实现,例如 synchronized,ReentrantLock,StampedLock 等。接下来会对这几种锁的使用进行详细讲解。
1. synchronized
synchronized 是 Java 中最简单,最常用的锁机制,可以用于修饰方法或代码块。在方法声明中使用 synchronized 关键字,则该方法成为同步方法,只允许一个线程访问该方法。在代码块中使用 synchronized 关键字,则该代码块成为同步块,只允许一个线程进入该代码块。
以下是 synchronized 的使用示例:
public class SynchronizedExample {
private int count = 0;
// 同步方法
public synchronized void increaseCount() {
count++;
}
// 同步块
public void increaseCountBlock() {
synchronized(this) {
count++;
}
}
}
在上述代码中,increaseCount 方法和 increaseCountBlock 方法都是线程安全的。
2. ReentrantLock
ReentrantLock 是在 JDK1.5 中引入的一个新的锁机制,相比 synchronized 更加灵活。ReentrantLock 可以支持中断等待锁的操作,而 synchronized 不支持。
以下是 ReentrantLock 的使用示例:
public class ReentrantLockExample {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increaseCount() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
在上述代码中,调用 increaseCount 方法时,首先获取锁(lock.lock()),执行 count++ 操作,最后释放锁(lock.unlock()),确保在同一时刻只有一个线程更新 count 变量的值。
3. StampedLock
StampedLock 是在 JDK1.8 中引入的一个新的锁机制,相比 ReentrantLock 更加高效。StampedLock 提供了三种模式:读,写和乐观读。读和写模式和 ReadWriteLock 违法,而乐观读模式则不需要获取锁。
以下是 StampedLock 的使用示例:
public class StampedLockExample {
private int count = 0;
private final StampedLock lock = new StampedLock();
public void increaseCount() {
long stamp = lock.writeLock();
try {
count++;
} finally {
lock.unlockWrite(stamp);
}
}
public int getCount() {
long stamp = lock.tryOptimisticRead();
int c = count;
if (!lock.validate(stamp)) {
stamp = lock.readLock();
try {
c = count;
} finally {
lock.unlockRead(stamp);
}
}
return c;
}
}
在上述代码中,increaseCount 方法获取写锁,执行 count++ 操作,unlockWrite 方法释放写锁。而 getCount 方法首先尝试乐观读锁(tryOptimisticRead),如果发现数据有被修改,则获取读锁(readLock)重新获取数据。在释放读锁(unlockRead)之前,需要再次验证数据是否被更改(validate)。
以上是 Java 锁的使用攻略,可以根据实际情况选择适合的锁来保证程序的线程安全。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:什么是Java锁? - Python技术站