在Java中,线程间的同步通常通过以下几种方式实现:
-
synchronized关键字:
synchronized
方法:在方法声明中加上synchronized
关键字,该方法在同一时间只能被一个线程访问。synchronized
块:使用synchronized(object)
语句来指定一个对象作为锁,只有持有该锁的线程才能进入该代码块。
示例:
java复制代码
public class SynchronizedExample { | |
private Object lock = new Object(); | |
public synchronized void synchronizedMethod() { | |
// 同步方法 | |
} | |
public void synchronizedBlock() { | |
synchronized (lock) { | |
// 同步块 | |
} | |
} | |
} |
- wait()和notify()/notifyAll()方法:
这两个方法必须用在synchronized
块或synchronized
方法中,因为它们需要获取对象的锁。wait()
方法会让当前线程等待,直到其他线程调用此对象的notify()
或notifyAll()
方法。
示例:
java复制代码
public class WaitNotifyExample { | |
private boolean flag = false; | |
public synchronized void waitMethod() throws InterruptedException { | |
while (!flag) { | |
wait(); // 当前线程等待,释放锁 | |
} | |
// 线程被唤醒后,继续执行后续代码 | |
} | |
public synchronized void notifyMethod() { | |
flag = true; | |
notify(); // 唤醒在此对象监视器上等待的单个线程 | |
// 或使用notifyAll()唤醒所有等待的线程 | |
} | |
} |
- Lock接口和Condition接口:
从Java 5开始,引入了java.util.concurrent.locks
包,提供了更灵活的锁和条件变量实现。Lock
接口是synchronized
方法或语句的替代,它提供了更详细的锁控制。Condition
接口替代了Object
的监视器方法(wait()
、notify()
和notifyAll()
)。
示例:
java复制代码
import java.util.concurrent.locks.Lock; | |
import java.util.concurrent.locks.Condition; | |
import java.util.concurrent.locks.ReentrantLock; | |
public class LockConditionExample { | |
private Lock lock = new ReentrantLock(); | |
private Condition condition = lock.newCondition(); | |
public void awaitMethod() throws InterruptedException { | |
lock.lock(); | |
try { | |
while (!someCondition) { | |
condition.await(); // 当前线程等待 | |
} | |
// 线程被唤醒后,继续执行后续代码 | |
} finally { | |
lock.unlock(); | |
} | |
} | |
public void signalMethod() { | |
lock.lock(); | |
try { | |
someCondition = true; | |
condition.signal(); // 唤醒在此条件上等待的单个线程 | |
// 或使用signalAll()唤醒所有等待的线程 | |
} finally { | |
lock.unlock(); | |
} | |
} | |
} |
- 原子类(Atomic Classes):
Java的java.util.concurrent.atomic
包提供了原子变量类,这些类可以在多线程环境中安全地更新某些类型的变量,而无需额外的同步。例如,AtomicInteger
、AtomicLong
、AtomicBoolean
等。
5. 线程安全的集合类:
Java的java.util.concurrent
包提供了一些线程安全的集合类,如ConcurrentHashMap
、CopyOnWriteArrayList
等,这些类可以在多线程环境中安全地使用。