多线程相关

一、CountDownLatch是什么?使用场景

CountDownLatch 是 Java 并发包中一个实用的同步工具,用于让一个或多个线程等待其他线程完成操作后再继续执行

使用场景:

(1)并行任务同步。

ABC三个线程分别直接不同的任务,常规做法可以让主线程sleep,但我们不知道需要执行多久,所以不知道sleep时间。这时可以使用CountDownLatch,每个线程执行完成一个就latch.countDown(),最后在主线程等待所有任务完成latch.await()。

 

二、Volatile使用场景

volatile关键字用于保证变量的可见性和有序性(禁止指令重排序)。

使用场景:

(1)线程的状态标志位

控制线程的运行 / 停止状态,确保一个线程修改状态后,其他线程能立即看到更新。

public class ShutdownableTask implements Runnable {
    private volatile boolean running = true;  // 停止标志

    @Override
    public void run() {
        while (running) {  // 循环处理任务
            processTask();
        }
    }

    public void shutdown() {
        running = false;  // 修改标志,立即对其他线程可见
    }
}

(2)双重检查锁定(DCL)单例模式

在实现线程安全的单例模式时,使用 volatile 禁止指令重排序,确保对象初始化的原子性

public class Singleton {
    private static volatile Singleton instance;  // 必须用 volatile

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {  // 第一次检查
            synchronized (Singleton.class) {
                if (instance == null) {  // 第二次检查
                    // 禁止指令重排序:先分配内存,再初始化对象,最后赋值引用
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

(3)对某个对象中的字段的进行原子更新

1. AtomicIntegerFieldUpdater 的作用

  • 允许在不使用 synchronized 或 AtomicInteger 的情况下,对对象的 volatile int 字段进行原子更新。
  • 通过反射机制实现,性能优于传统锁,适用于热点字段的更新。

2. 必须搭配 volatile 的原因

  • AtomicIntegerFieldUpdater 要求目标字段必须被声明为 volatile,以确保:
    • 可见性:一个线程的修改能立即被其他线程看到。
    • 内存屏障:禁止指令重排序,保证原子操作的正确性。

比如用户首页有一个数据统计,在后台是通过多线程批量去处理数据的,完成后对某个统计字段更新。

posted @ 2025-05-28 16:24  幻月hah  阅读(5)  评论(0)    收藏  举报