Java并发容器、框架、工具类

1. 并发容器

1.1 读写分离的CopyOnWriteArrayList

线程安全、读操做无锁的ArrayList。html

基本思想:当咱们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,而后新的容器里添加元素,添加完元素以后,再将原容器的引用指向新的容器。这样作的好处是咱们能够对CopyOnWrite容器进行并发的读,而不须要加锁,由于当前容器不会添加任何元素。因此CopyOnWrite容器也是一种读写分离的思想,读和写不一样的容器。java

CopyOnWrite并发容器用于读多写少的并发场景。缺点:(1)内存占用问题;(2)只能保证数据的最终一致性,不能保证数据的实时一致性。面试

深刻分析可参考:并发编程网-聊聊并发-Java中的Copy-On-Write容器编程

1.2 读写分离的CopyOnWriteArraySet

基于CopyOnWriteArrayList实现,原理相似,add操做要遍历数组以免添加剧复元素。数组

2. 并发工具类

2.1 等待多线程完成的CountDownLatch

等待多线程完成的CountDownLatch,实现异步转同步操做。安全

深刻分析可参考:并发编程网-并发工具类(一)等待多线程完成的CountDownLatch多线程

2.2 同步屏障CyclicBarrier

比CountDownLatch更强大,当await的数量到达指定数量后,才继续往下执行。通俗点讲就是:让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,全部被屏障拦截的线程才会继续运行。多用于多线程计算数据,最后合并计算结果的场景。并发

深刻分析可参考:程序猿DD-死磕Java并发:J.U.C之并发工具类:CyclicBarrier异步

2.3 控制并发线程数的Semphore

控制某资源被同时访问个数,是对锁的扩展,指定多个线程访问某一资源。对于临界区管理代码,程序会限制同时执行这段代码的线程数。ide

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * Semaphore实现限流案例
 */
public class Main {
    /**
     * 申请信号量准入数,即同时能申请多少个许可
     */
    static Semaphore semaphore = new Semaphore(10);

    public static void main(String[] args) throws Exception {
        final Executor executor = Executors.newFixedThreadPool(1000);
        for (int i = 0; i < 2000; i++) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    executor();
                }
            });
        }
    }
    public static void executor() {
        try {
            if (semaphore.getQueueLength() > 10) {
                System.out.println("wait...");
                return;
            }
            /**
             * 尝试得到一个许可,若存在可用资源,直接返回
             * 不然进入等待队列,不断尝试得到资源,而tryAcquire不会等待
             */
            semaphore.acquire();
            // 模拟耗时的业务逻辑
            Thread.sleep(1000);
            System.out.println("run...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 将信号量释放,以便其余请求能够得到空闲资源
            semaphore.release();
        }
    }

}

2.4 线程间交换数据的Exchanger

交换者是用于线程间协做的工具类,用于线程间的数据交换,它提供一个同步点,在这个同步点,两个线程能够交换彼此的数据。

深刻分析能够参考:芋道源码-【死磕 Java 并发】—– J.U.C 之并发工具类:Exchanger

2.5 异步任务FutureTask

五月的仓颉-Java多线程21:多线程下的其余组件之CyclicBarrier、Callable、Future和FutureTask

2.6 线程访问隔离ThreadLocal

归纳起来讲,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不一样的线程排队访问,然后者为每个线程都提供了一份变量,所以能够同时访问而互不影响。

程序猿DD-「图解」ThreadLocal 在并发问题中的应用(原理剖析、InheritableThreadLocal)

占小狼的博客-面试官再问你ThreadLocal,你就这样“怼”回去(使用场景及最佳实践)

相关文章
相关标签/搜索