一文彻底搞懂JUC结构

1. JUC结构图

JUC 是 Java 并发工具包(Java Util Concurrency),它是 Java 标准库提供的一组用于支持多线程编程的工具和类库。JUC 提供了丰富的并发工具和数据结构,能够帮助我们更方便地编写多线程程序,提高并发性能和可维护性。
在这里插入图片描述

2. tools(工具类)

又叫信号量三组工具类,包含:

  • CountDownLatch(闭锁) 是一个同步辅助类,用于实现一组线程的等待/通知机制。它维护了一个计数器,初始化时设置一个计数值,每个线程在完成任务后调用 countDown 方法将计数值减一,当计数值减至零时,所有等待的线程都会被释放。CountDownLatch 可以用于实现线程间的协调和同步,等待所有线程完成后再执行后续操作。

  • CyclicBarrier(栅栏) 用于实现一组线程的同步点,它维护了一个屏障,当所有线程都达到了同步点后,屏障会打开,所有线程可以继续执行。与 CountDownLatch 不同的是,CyclicBarrier 可以循环使用,即在所有线程达到同步点后,可以重置屏障并重新开始下一轮同步。CyclicBarrier 可以用于实现线程间的同步和协作,例如分阶段并行任务的同步。

  • Semaphore(信号量) 是一个计数信号量,用于控制同时访问某个资源的线程数量,它的本质是一个“共享锁“。它维护了一个计数器,表示当前可用的许可数,线程在访问资源之前需要先调用 acquire()获取许可,如果许可数大于 0,则线程可以获取许可并继续执行,许可数减一;如果许可数等于 0,则线程需要等待其他线程释放许可。Semaphore 可以用于限流、并发控制等场景。

3. executor(执行者)

在 Java 中,Executor 接口是线程执行的顶级接口,用于表示一种执行线程任务的抽象。而 ExecutorService 接口则是 Executor 的子接口,它扩展了 Executor 接口,并提供了更丰富的线程池功能和管理方法。常见的 ExecutorService 的实现类:

  • ThreadPoolExecutor:ThreadPoolExecutor 是 Java 中最常用的线程池实现类,它提供了一个可调整大小的线程池,可以灵活控制线程数量和队列容量,适用于各种类型的任务执行场景。

  • ScheduledThreadPoolExecutor:ScheduledThreadPoolExecutor 是 ThreadPoolExecutor 的子类,它提供了定时执行任务的功能,可以按照一定的时间间隔或延迟时间执行任务。

  • ForkJoinPool:ForkJoinPool 是一种特殊的线程池实现,专门用于执行分治任务。它采用工作窃取(Work-Stealing)算法,能够高效地处理递归划分的任务,并充分利用多核处理器的性能。

  • SingleThreadExecutor:SingleThreadExecutor 是只包含一个工作线程的线程池,所有任务都在同一个线程中按顺序执行,适用于需要保证任务顺序执行和线程安全的场景。

  • CachedThreadPool:CachedThreadPool 是一个根据需要创建新线程的线程池,当线程池中的线程空闲时间超过设定的超时时间时,会被销毁,适用于执行短期异步任务的场景。

4. atomic(原子性包)

JDK提供的一组原子操作类,用于在多线程环境下进行原子性操作。这些原子操作类能够保证某些操作的原子性,即在执行这些操作时不会被其他线程中断,从而避免了线程安全问题。

包含有AtomicBoolean、AtomicInteger、AtomicIntegerArray等原子变量类,他们的实现原理大多是持有它们各自的对应的类型变量value,而且被volatile关键字修饰了。这样来保证每次一个线程要使用它都会拿到最新的值。volatile 关键字的作用是确保变量在多线程环境中的可见性,当一个线程修改了变量的值时,其他线程能够立即看到这个变化。结合原子操作,这些原子变量类能够确保在多线程环境中对变量的操作是线程安全的。

原子操作类可以用于替代传统的加锁机制,提供了一种更轻量级的线程安全解决方案。它们的操作是原子性的,不需要显式地使用 synchronized 关键字进行同步,因此在一些高并发场景下能够提供更好的性能表现。

5. locks(锁包)

JDK提供的锁机制,相比synchronized关键字来进行同步锁,功能更加强大,它为锁提供了一个框架,该框架允许更灵活地使用锁包含的实现类有:

  • ReentrantLock:是可重入锁的实现类,它提供了与 synchronized 关键字类似的功能,但比 synchronized 更加灵活。它支持公平性和非公平性两种竞争方式,并提供了额外的功能,如可中断锁、可轮询锁、超时锁等。
  • ReentrantReadWriteLock:是可重入读写锁的实现类,它维护了一对相关的锁,分别用于读操作和写操作。读锁是共享锁,多个线程可以同时持有读锁进行读操作,但写锁是排它锁,只能有一个线程持有写锁进行写操作。
  • StampedLock:是 JDK 8 引入的一种乐观读写锁的实现类,它支持更高级别的并发控制,包括乐观读、悲观读、悲观写等模式。与 ReentrantReadWriteLock 相比,StampedLock 在某些情况下可以提供更好的性能。
  • LockSupport:是线程阻塞工具类,提供了与线程的阻塞和唤醒相关的方法。它通常与锁一起使用,用于实现各种同步控制的机制。
  • Condition:是条件对象的接口,它通常与锁一起使用,用于实现等待和通知的机制。通过 Condition 可以实现更精细的线程等待和唤醒逻辑。

这些锁类提供了丰富的功能和灵活的接口,能够满足各种不同的并发编程需求。相比于传统的 synchronized 关键字,它们提供了更多的控制和更高级别的并发处理方式,能够提高程序的性能和可维护性。

6. collections(集合类)

主要是提供了一些线程安全的集合类,以确保在多线程环境下对集合的操作是线程安全的。常见的线程安全集合类:

  • ConcurrentHashMap:是线程安全的哈希表实现,支持高并发的读写操作。它采用分段锁(Segment)的方式实现,并发度较高,多个线程可以同时执行读操作,而写操作仅针对特定的分段锁进行,不会阻塞其他线程的读操作。
  • CopyOnWriteArrayList:是线程安全的动态数组实现,内部使用写时复制(Copy-On-Write)的方式来保证线程安全。每次修改操作(如添加、删除元素)都会创建一个新的副本,因此写操作比较慢,但读操作无锁,性能较高,适用于读多写少的场景。
  • CopyOnWriteArraySet:是线程安全的集合类,内部基于 CopyOnWriteArrayList 实现,保证了集合的线程安全性。它与 HashSet 类似,但是线程安全,并且不允许重复元素。
  • ConcurrentSkipListMap:是线程安全的跳表实现,支持并发的读写操作。它是基于跳表数据结构实现的有序映射表,具有较高的并发度和较快的查找、插入、删除等操作。
  • ConcurrentSkipListSet:是线程安全的有序集合类,内部基于 ConcurrentSkipListMap 实现。它是有序集合,不允许重复元素,并且支持并发的读写操作。

线程安全的集合类提供了在多线程环境下进行集合操作的安全保障,能够有效地避免线程安全问题的发生。它们适用于高并发的场景,能够提高程序的并发性能和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值