← 返回首页
🔐

Java synchronized深入:锁机制与优化

📂 java ⏱ 3 min 443 words

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. 最佳实践

  1. 减少锁的范围:只同步必要的代码
  2. 使用细粒度锁:避免大对象锁
  3. 避免死锁:按固定顺序获取锁
  4. 使用volatile:确保可见性
  5. 优先使用并发工具:ExecutorService、BlockingQueue等

总结

synchronized是Java中最基本的同步机制。理解其工作原理和优化策略,可以编写高效的并发程序。在实际编程中,要合理使用synchronized,避免性能问题。