Java线程同步流程如何规范

wen java案例 31

本文目录导读:

Java线程同步流程如何规范

  1. 同步方法选择规范
  2. 锁的使用规范
  3. 等待/通知模式规范
  4. 可见性保证规范
  5. 线程安全类设计规范
  6. 并发容器使用规范
  7. 性能优化规范
  8. 最佳实践总结

我来详细说明Java线程同步的规范流程,包括最佳实践和常见模式。

同步方法选择规范

1 优先选择高级并发工具

// ✅ 推荐:使用 java.util.concurrent 包
public class ConcurrentCounter {
    private final AtomicInteger count = new AtomicInteger(0);
    public void increment() {
        count.incrementAndGet();
    }
    public int getCount() {
        return count.get();
    }
}

2 使用synchronized的场景

public class ThreadSafeList {
    private final List<String> list = new ArrayList<>();
    // 明确指定锁对象
    public synchronized void add(String item) {
        list.add(item);
    }
    // 或者使用显式锁对象
    private final Object lock = new Object();
    public void remove(String item) {
        synchronized (lock) {
            list.remove(item);
        }
    }
}

锁的使用规范

1 ReentrantLock规范使用

public class BankAccount {
    private final ReentrantLock lock = new ReentrantLock();
    private double balance;
    public void transfer(double amount) {
        lock.lock();  // 必须在try之前获取锁
        try {
            // 业务逻辑
            balance += amount;
        } finally {
            lock.unlock();  // 必须在finally中释放
        }
    }
    // 带超时的锁
    public boolean tryTransfer(double amount, long timeout) 
            throws InterruptedException {
        if (lock.tryLock(timeout, TimeUnit.MILLISECONDS)) {
            try {
                balance += amount;
                return true;
            } finally {
                lock.unlock();
            }
        }
        return false;
    }
}

2 ReadWriteLock使用规范

public class Cache<K, V> {
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Map<K, V> map = new HashMap<>();
    public V get(K key) {
        rwLock.readLock().lock();
        try {
            return map.get(key);
        } finally {
            rwLock.readLock().unlock();
        }
    }
    public void put(K key, V value) {
        rwLock.writeLock().lock();
        try {
            map.put(key, value);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
}

等待/通知模式规范

1 标准wait/notify模式

public class BlockingQueue<T> {
    private final Queue<T> queue = new LinkedList<>();
    private final int capacity;
    public synchronized void put(T item) throws InterruptedException {
        while (queue.size() == capacity) {
            wait();  // 必须使用while循环检查条件
        }
        queue.add(item);
        notifyAll();  // 优先使用notifyAll而非notify
    }
    public synchronized T take() throws InterruptedException {
        while (queue.isEmpty()) {
            wait();
        }
        T item = queue.poll();
        notifyAll();
        return item;
    }
}

2 Condition使用规范

public class ConditionExample {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notEmpty = lock.newCondition();
    private final Condition notFull = lock.newCondition();
    private final Queue<Object> queue = new LinkedList<>();
    private final int maxSize = 10;
    public void put(Object item) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == maxSize) {
                notFull.await();
            }
            queue.add(item);
            notEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }
    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                notEmpty.await();
            }
            Object item = queue.poll();
            notFull.signalAll();
            return item;
        } finally {
            lock.unlock();
        }
    }
}

可见性保证规范

1 volatile的正确使用

public class FlagExample {
    // volatile确保可见性,但不保证原子性
    private volatile boolean running = true;
    public void stop() {
        running = false;  // 单线程写操作安全
    }
    public void run() {
        while (running) {  // 多线程读操作
            // 业务逻辑
        }
    }
}

2 final的线程安全使用

public class ImmutableObject {
    private final int id;
    private final String name;
    private final List<String> items;
    public ImmutableObject(int id, String name, List<String> items) {
        this.id = id;
        this.name = name;
        // 防御性复制
        this.items = Collections.unmodifiableList(new ArrayList<>(items));
    }
    // 只有getter,没有setter
    public int getId() { return id; }
    public String getName() { return name; }
    public List<String> getItems() { return items; }
}

线程安全类设计规范

1 线程安全单例

public class ThreadSafeSingleton {
    // 枚举方式(最推荐)
    private enum Singleton {
        INSTANCE;
        private final ThreadSafeSingleton instance;
        Singleton() {
            instance = new ThreadSafeSingleton();
        }
        public ThreadSafeSingleton getInstance() {
            return instance;
        }
    }
    public static ThreadSafeSingleton getInstance() {
        return Singleton.INSTANCE.getInstance();
    }
}
// 双重检查锁定(适用于低版本Java)
public class DoubleCheckedSingleton {
    private static volatile DoubleCheckedSingleton instance;
    private DoubleCheckedSingleton() {}
    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}

并发容器使用规范

public class ConcurrentCollectionExample {
    // 优先使用并发容器而非同步容器
    private final ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
    private final CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
    private final BlockingQueue<String> queue = new LinkedBlockingQueue<>(100);
    // 原子性的复合操作
    public void putIfAbsent(String key, String value) {
        map.putIfAbsent(key, value);  // 原子操作
    }
    // 避免在迭代时修改
    public void safeIteration() {
        for (String item : list) {  // CopyOnWriteArrayList允许迭代时修改
            System.out.println(item);
        }
    }
}

性能优化规范

1 锁粒度控制

public class LockGranularity {
    // ❌ 锁粒度过大
    public synchronized void processAll() {
        longRunningOperation1();
        fastOperation();
        longRunningOperation2();
    }
    // ✅ 锁粒度适中
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();
    public void processOptimized() {
        longRunningOperation1();  // 不需要同步
        synchronized (lock1) {
            fastOperation();  // 只需要同步关键部分
        }
        longRunningOperation2();  // 不需要同步
    }
}

最佳实践总结

1 同步选择建议

场景 推荐方案 说明
简单计数 AtomicInteger 无锁CAS操作
少量共享数据 synchronized 实现简单,自动管理
复杂并发控制 ReentrantLock 灵活的锁机制
读写分离 ReadWriteLock 读多写少场景
生产者消费者 BlockingQueue 自带等待通知机制

2 常见陷阱避免

public class CommonPitfalls {
    // ❌ 不要锁字符串常量
    private final String LOCK = new String("LOCK");  // 应该使用new创建
    // ✅ 正确的锁对象
    private final Object lock = new Object();
    // ❌ 不要在同步块中调用sleep
    public synchronized void badMethod() throws InterruptedException {
        Thread.sleep(1000);  // 持有锁时sleep
    }
    // ✅ 正确的做法
    public void goodMethod() throws InterruptedException {
        longRunningOperation();
        synchronized (lock) {
            criticalSection();
        }
    }
}

3 检查清单

  1. 锁获取/释放:确保配对,在finally中释放
  2. 等待条件:始终使用while循环检查
  3. 可见性:使用volatile或加锁确保可见性
  4. 原子性:对复合操作使用同步
  5. 死锁预防:按固定顺序获取多个锁
  6. 性能考虑:最小化同步块范围

遵循这些规范可以构建出既安全又高效的并发Java程序。

抱歉,评论功能暂时关闭!