Synchronized关键字
外观
概述[编辑 | 编辑源代码]
synchronized是Java中用于实现线程同步的关键字,它能够确保同一时刻只有一个线程可以访问被同步的代码块或方法,从而解决多线程环境下的数据竞争问题。其核心功能包括:
- 原子性:保证操作的不可分割性。
- 可见性:确保线程对共享变量的修改对其他线程立即可见。
- 有序性:防止指令重排序导致的并发问题。
语法形式[编辑 | 编辑源代码]
`synchronized`可通过以下三种方式使用:
1. 同步实例方法[编辑 | 编辑源代码]
修饰非静态方法,锁对象是当前实例(`this`)。
public synchronized void increment() {
// 线程安全的代码
}
2. 同步静态方法[编辑 | 编辑源代码]
修饰静态方法,锁对象是当前类的`Class`对象。
public static synchronized void staticIncrement() {
// 线程安全的静态方法
}
3. 同步代码块[编辑 | 编辑源代码]
指定任意对象作为锁,灵活性更高。
public void blockSync() {
synchronized (lockObject) {
// 线程安全的代码块
}
}
底层原理[编辑 | 编辑源代码]
`synchronized`通过JVM内置的监视器锁(Monitor)实现,其工作流程如下:
- 在JDK 1.6后引入锁优化机制,包括:
* 偏向锁(Biased Locking) * 轻量级锁(Lightweight Locking) * 自旋锁(Spin Locking) * 锁消除(Lock Elimination)
代码示例[编辑 | 编辑源代码]
计数器案例[编辑 | 编辑源代码]
以下示例展示未同步和同步的计数器区别:
class UnsafeCounter {
private int count = 0;
public void add() {
count++; // 非原子操作
}
}
class SafeCounter {
private int count = 0;
public synchronized void add() {
count++; // 原子操作
}
}
执行测试代码:
public static void main(String[] args) throws InterruptedException {
final SafeCounter safe = new SafeCounter();
final UnsafeCounter unsafe = new UnsafeCounter();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
safe.add();
unsafe.add();
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("SafeCounter: " + safe.getCount()); // 输出2000
System.out.println("UnsafeCounter: " + unsafe.getCount()); // 可能小于2000
}
锁的存储结构[编辑 | 编辑源代码]
对象头中的Mark Word存储锁状态信息:
锁状态转换关系:
实际应用场景[编辑 | 编辑源代码]
1. 单例模式实现[编辑 | 编辑源代码]
class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
2. 线程安全集合包装[编辑 | 编辑源代码]
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
注意事项[编辑 | 编辑源代码]
- 避免锁粒度过大(如直接同步整个方法)
- 防止死锁(按固定顺序获取多把锁)
- 优先使用`java.util.concurrent`包中的高级工具类
性能对比[编辑 | 编辑源代码]
同步方式 | JDK 1.6 | JDK 11 |
---|---|---|
无同步 | 5 | 3 |
synchronized | 20 | 15 |
ReentrantLock | 18 | 12 |