在 Java 中,有以下四种常见的线程同步方式:
1. synchronized 关键字:使用 synchronized 关键字可以实现对象级别的同步,确保同一时间只有一个线程可以访问被 synchronized 修饰的代码块或方法。当一个线程进入 synchronized 代码块时,它会锁定该对象,其他线程必须等待锁释放后才能访问。
示例:
synchronized (lockObject) {
// 同步的代码块
}
// 或
public synchronized void synchronizedMethod() {
// 同步的方法
}
2. ReentrantLock 类:ReentrantLock 是 Java.util.concurrent 包提供的一种可重入的互斥锁。与 synchronized 相比,ReentrantLock 提供了更多的灵活性,如可中断锁、超时锁等。使用 ReentrantLock 必须显式地获取锁和释放锁。
示例:
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// 同步的代码块
} finally {
lock.unlock();
}
3. Semaphore 信号量:Semaphore 是一种计数信号量,它可以控制同时访问某个资源的线程数量。通过调用 acquire() 方法获取许可,release() 方法释放许可。
示例:
Semaphore semaphore = new Semaphore(1);
semaphore.acquire();
try {
// 同步的代码块
} finally {
semaphore.release();
}
4. Condition 条件变量:Condition 是在使用 Lock 对象时提供类似于 wait() 和 notify() 的等待/通知机制。可以使用 Condition 的 await() 方法等待某个条件满足,signal() 方法唤醒等待的线程。
示例:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while (!conditionMet) {
condition.await();
}
// 同步的代码块
} finally {
lock.unlock();
}
这些线程同步方式可以帮助解决多线程并发访问共享资源时的竞态条件和数据不一致问题。选择适当的同步方式取决于具体的需求和场景,需要根据实际情况进行选择。