Java synchronized深入:锁机制与优化
Java synchronized深入:锁机制与优化
概述
synchronized是Java中最基本的同步机制。本教程深入介绍synchronized的工作原理、锁升级和优化策略。
1. synchronized基础
对象锁和类锁
public class SynchronizedBasic {
// 对象锁
public synchronized void objectLock() {
System.out.println("对象锁: " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 类锁
public static synchronized void classLock() {
System.out.println("类锁: " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 同步代码块
public void blockLock() {
synchronized (this) {
System.out.println("代码块锁: " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
SynchronizedBasic obj = new SynchronizedBasic();
// 对象锁测试
Thread t1 = new Thread(() -> obj.objectLock());
Thread t2 = new Thread(() -> obj.objectLock());
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---");
// 类锁测试
Thread t3 = new Thread(() -> SynchronizedBasic.classLock());
Thread t4 = new Thread(() -> SynchronizedBasic.classLock());
t3.start();
t4.start();
}
}
2. 锁升级
import java.util.concurrent.atomic.*;
public class LockEscalation {
// 锁升级过程:
// 1. 无锁状态
// 2. 偏向锁:只有一个线程访问
// 3. 轻量级锁:多个线程交替访问
// 4. 重量级锁:多个线程同时访问
private int count = 0;
private final Object lock = new Object();
// 无锁
public void noLock() {
count++;
}
// 偏向锁
public synchronized void biasedLock() {
count++;
}
// 轻量级锁
public void lightweightLock() {
synchronized (lock) {
count++;
}
}
public static void main(String[] args) throws InterruptedException {
LockEscalation obj = new LockEscalation();
// 模拟偏向锁:单线程访问
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
obj.biasedLock();
}
});
t1.start();
t1.join();
System.out.println("偏向锁测试完成");
// 模拟轻量级锁:多线程交替访问
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
obj.lightweightLock();
}
});
Thread t3 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
obj.lightweightLock();
}
});
t2.start();
t3.start();
t2.join();
t3.join();
System.out.println("轻量级锁测试完成");
}
}
3. 实际应用示例
线程安全的单例模式
public class ThreadSafeSingleton {
private static volatile ThreadSafeSingleton instance;
private ThreadSafeSingleton() {}
// 双重检查锁定
public static ThreadSafeSingleton getInstance() {
if (instance == null) {
synchronized (ThreadSafeSingleton.class) {
if (instance == null) {
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
// 静态内部类(推荐)
private static class Holder {
private static final ThreadSafeSingleton INSTANCE = new ThreadSafeSingleton();
}
public static ThreadSafeSingleton getInstance2() {
return Holder.INSTANCE;
}
}
线程安全的集合
import java.util.concurrent.*;
public class ThreadSafeCollection {
// ConcurrentHashMap
private final ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// CopyOnWriteArrayList
private final CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
// BlockingQueue
private final BlockingQueue<String> queue = new LinkedBlockingQueue<>();
public void addToMap(String key, int value) {
map.put(key, value);
}
public int getFromMap(String key) {
return map.getOrDefault(key, 0);
}
public void addToList(String item) {
list.add(item);
}
public void addToQueue(String item) throws InterruptedException {
queue.put(item);
}
public String takeFromQueue() throws InterruptedException {
return queue.take();
}
}
4. 最佳实践
- 减少锁的范围:只同步必要的代码
- 使用细粒度锁:避免大对象锁
- 避免死锁:按固定顺序获取锁
- 使用volatile:确保可见性
- 优先使用并发工具:ExecutorService、BlockingQueue等
总结
synchronized是Java中最基本的同步机制。理解其工作原理和优化策略,可以编写高效的并发程序。在实际编程中,要合理使用synchronized,避免性能问题。