JavaGuide自学记录2--Java集合源码+一些特殊类


JavaGuide自学记录2–Java集合源码+一些特殊类

CopyOnWriteArrayList

JDK1.5 引入了 Java.util.concurrent(JUC)包,其中唯一的线程安全 List 实现就是 CopyOnWriteArrayList

CopyOnWriteArrayList 线程安全的核心在于其采用了 写时复制(Copy-On-Write) 的策略,从 CopyOnWriteArrayList 的名字就能看出了。

当需要修改( addsetremove 等操作) CopyOnWriteArrayList 的内容时,不会直接修改原数组,而是会先创建底层数组的副本,对副本数组进行修改,修改完之后再将修改后的数组赋值回去,这样就可以保证写操作不会影响读操作了。

只有写写会互斥,则读写不互斥,会有一些数据不一致问题。

阻塞队列和非阻塞队列

Java 提供的线程安全的 Queue 可以分为阻塞队列非阻塞队列,其中阻塞队列的典型例子是 BlockingQueue,非阻塞队列的典型例子是 ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 阻塞队列可以通过加锁来实现,非阻塞队列可以通过 CAS 操作实现

当然ArrayBlockingQueue也能做非阻塞

AtomicInteger 线程安全原理简单分析

AtomicInteger类的部分源码:

    // setup to use Unsafe.compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用)
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作,从而避免synchronized 的高开销,执行效率大为提升。

CAS 的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址。另外 value 是一个 volatile 变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。

异步编排 CompletableFuture

Java里面的

京东的 asyncTool 这个并发框架,里面大量使用到了 CompletableFuture

从 RocketMQ 4.7 开始,RocketMQ 引入了 CompletableFuture来实现异步消息处理 。

其他JavaGuide的集合类

LinkedHashMap可以实现LRU算法

DelayQueue 底层是使用优先队列 PriorityQueue 来存储元素,为了保证线程安全使用了ReentrantLock,

DelayQueue 通常用于实现定时任务调度和缓存过期删除等场景。

AQS

ThreadLocal


文章作者: 爱敲代码の鱼儿
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 爱敲代码の鱼儿 !
  目录