在Java中,互斥锁是一种同步机制,用于控制对共享资源的访问,以防止多个线程同时访问该资源,从而避免数据竞争和一致性问题。互斥锁确保一次只有一个线程可以执行特定代码段。
Java提供了几种实现互斥锁的方式,以下是一些常见的实现方法:
synchronized关键字: synchronized
可以用来同步方法或代码块。当一个线程访问一个对象的synchronized
方法或代码块时,它会获得该对象的锁,其他线程必须等待直到锁被释放。
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
ReentrantLock类: ReentrantLock
是java.util.concurrent.locks
包中的一个类,提供了更灵活的锁定操作。它允许更细粒度的锁定控制,例如尝试非阻塞获取锁、尝试超时获取锁等。
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
}
显式锁(Locks): 除了ReentrantLock
,Java还提供了其他类型的锁,如ReadWriteLock
,它允许多个读操作同时进行,但写操作是互斥的。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Counter {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private int count = 0;
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();
}
}
}
使用互斥锁时,重要的是要确保在访问共享资源后释放锁,以避免死锁。在synchronized
方法或代码块中,锁会在方法或代码块执行完毕后自动释放。在使用ReentrantLock
等显式锁时,需要在finally
块中显式释放锁。