Java 线程同步与锁机制
多线程环境下,共享资源的访问需要同步机制来保证线程安全。理解同步和锁机制是编写正确并发程序的关键。本章将详细介绍 Java 中的线程同步机制。
synchronized 关键字
synchronized 方法
使用 synchronized 修饰方法,锁对象是当前实例(this)。
public class Counter {
private int count = 0;
// 同步方法
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
等价于:
public void increment() {
synchronized (this) {
count++;
}
}
synchronized 代码块
使用 synchronized 代码块,可以指定锁对象。
public class Counter {
private int count = 0;
private final Object lock = new Object();
public void increment() {
synchronized (lock) { // 使用指定对象作为锁
count++;
}
}
}
静态同步方法
静态同步方法的锁对象是类对象(Class 对象)。
public class Counter {
private static int count = 0;
// 静态同步方法
public static synchronized void increment() {
count++;
}
}
等价于:
public static void increment() {
synchronized (Counter.class) {
count++;
}
}
synchronized 的特点
特点:
- 可重入:同一线程可以多次获取同一把锁
- 互斥:同一时刻只有一个线程可以执行
- 自动释放:方法执行完毕或异常时自动释放锁
- 不可中断:获取锁的过程不可中断
public class ReentrantExample {
public synchronized void method1() {
System.out.println("method1");
method2(); // 可以调用,因为可重入
}
public synchronized void method2() {
System.out.println("method2");
}
}
显示锁(ReentrantLock)
ReentrantLock
**ReentrantLock**是 Java 5 引入的显示锁,功能比 synchronized 更强大。
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock(); // 获取锁
try {
count++;
} finally {
lock.unlock(); // 释放锁(必须在 finally 中)
}
}
}