java多线程如何同步问题
多线程同步的基本概念
多线程同步是为了解决多个线程访问共享资源时的数据一致性和线程安全问题。Java提供了多种机制实现线程同步,包括synchronized关键字、Lock接口、原子类等。
使用synchronized关键字
synchronized是Java中最基础的同步机制,可以修饰方法或代码块,确保同一时间只有一个线程执行被保护的代码。
同步方法:
public synchronized void increment() {
// 线程安全的代码
}
同步代码块:
public void increment() {
synchronized (this) {
// 线程安全的代码
}
}
使用Lock接口
java.util.concurrent.locks.Lock提供了更灵活的锁机制,例如ReentrantLock。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
// 线程安全的代码
} finally {
lock.unlock();
}
}
使用原子类
java.util.concurrent.atomic包提供了原子类(如AtomicInteger),通过CAS(Compare-And-Swap)实现无锁线程安全。

import java.util.concurrent.atomic.AtomicInteger;
private AtomicInteger counter = new AtomicInteger(0);
public void increment() {
counter.incrementAndGet();
}
使用volatile关键字
volatile确保变量的可见性,但不保证原子性。适用于单个变量的简单操作。
private volatile boolean flag = false;
使用wait()和notify()
通过Object类的wait()和notify()实现线程间通信,通常与synchronized配合使用。
public synchronized void waitForCondition() throws InterruptedException {
while (!condition) {
wait();
}
}
public synchronized void notifyCondition() {
condition = true;
notifyAll();
}
使用CountDownLatch和CyclicBarrier
CountDownLatch和CyclicBarrier是高级同步工具,适用于多线程协作场景。
CountDownLatch示例:

import java.util.concurrent.CountDownLatch;
CountDownLatch latch = new CountDownLatch(3);
// 线程中调用
latch.countDown();
latch.await(); // 等待所有线程完成
CyclicBarrier示例:
import java.util.concurrent.CyclicBarrier;
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
// 所有线程到达后执行的任务
});
// 线程中调用
barrier.await();
使用Semaphore
Semaphore控制同时访问资源的线程数量,适用于资源池或限流场景。
import java.util.concurrent.Semaphore;
Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问
public void accessResource() throws InterruptedException {
semaphore.acquire();
try {
// 访问资源
} finally {
semaphore.release();
}
}
线程安全的集合类
java.util.concurrent包提供了线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等。
import java.util.concurrent.ConcurrentHashMap;
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 1);
避免死锁
死锁是多线程中常见问题,通常由多个线程互相等待对方释放锁引起。避免死锁的方法包括:
- 按固定顺序获取锁。
- 使用
tryLock()设置超时时间。 - 避免嵌套锁。
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
// 按固定顺序获取锁
public void method1() {
lock1.lock();
try {
lock2.lock();
try {
// 业务逻辑
} finally {
lock2.unlock();
}
} finally {
lock1.unlock();
}
}






