1.JUC之CountDownLatch与CyclicBarrier
2.八股文JUC知识总结
3.Java大厂面试100道题( JUC篇)
JUC之CountDownLatch与CyclicBarrier
在java.util.concurrent包中,障源障代CountDownLatch与CyclicBarrier是码屏码用于线程同步的工具类。CountDownLatch允许一个或多个线程等待直到其他线程完成一组操作。障源障代类比于等待所有小伙伴上车后再出发的码屏码春游场景,通过使用CountDownLatch,障源障代我们可以更简洁地实现这一需求。码屏码奕力烧录软件源码CountDownLatch包含创建、障源障代减计数以及等待计数器为零等方法。码屏码
CyclicBarrier则允许一组线程在达到共同屏障点后等待彼此,障源障代直至所有线程都执行完毕。码屏码这个工具类可以模拟赛跑比赛,障源障代所有运动员在起跑线前等待,码屏码直到所有运动员准备完毕,障源障代比赛正式开始。码屏码CyclicBarrier具有构造方法、障源障代等待所有线程达到屏障的方法以及重置计数值的能力。
CountDownLatch与CyclicBarrier在使用场景和功能上有所区别。CountDownLatch适用于一个或多个线程等待其他线程执行完毕后继续执行的场景,而CyclicBarrier则适用于一组线程在达到共同点后等待彼此的场景。CountDownLatch强调计数,最终计数为零后线程执行,CyclicBarrier强调共同等待,直到所有线程到达同一屏障点。
总结来说,103规约源码值4095CountDownLatch与CyclicBarrier均提供了线程同步的功能,但CountDownLatch侧重于计数控制,而CyclicBarrier侧重于共同等待机制。在实际开发中,根据具体场景选择合适的工具类,可以更高效地管理线程同步问题。
八股文JUC知识总结
并发编程,如同一股清流,旨在最大化多核CPU的潜力,提升性能和处理能力,但同时也伴随着一些挑战,如内存泄露、频繁的上下文切换、线程安全难题和死锁的威胁。其中,上下文切换是CPU通过时间片机制切换线程的关键步骤。
探索并行编程的路径多种多样,你可选择四种方式来创建线程:一是继承自Java的Thread类,二是通过实现Runnable接口,三是依赖Callable接口的返回值特性,四是借助Executor工具类的灵活性。Runnable模式虽无返回值,但Callable则提供了返回值处理和异常管理的教育网站源码cms可能。
线程的生命周期包括五个阶段:新建、就绪、运行、阻塞(包括等待、同步阻塞和其他形式)以及消亡。并发编程的三大基石——原子性、可见性和有序性,是保证并发操作正确性的核心要素,Atomic类、synchronized和Lock接口为我们提供了相应的解决方案。synchronized,作为Java的灵魂关键字,通过互斥、缓存刷新和处理器顺序保证了这三大特性。
深入理解synchronized的底层机制,你会发现它拥有从偏向锁、轻量级锁到重量级锁的升级过程。非竞争时,偏向锁能快速获取,而在竞争中会升级为轻量级锁,自旋尝试不阻塞。然而,当竞争加剧,证书生成查询源码锁会变为重量级,造成性能损失。volatile关键字则强调可见性和有序性,而非原子性操作。内存屏障则守护数据一致性,防止重排序带来的问题。
对于更高级的锁控制,如ReentrantLock,它提供了可重入、中断选项和公平性选择,比synchronized更为灵活。AQS(AbstractQueuedSynchronizer)则作为基础框架,为构建复杂同步器提供了强大支持。在并发工具中,线程池是必不可少的一部分,它能节省资源、优化响应速度,如FixedThreadPool、ScheduledThreadPool等各有其适用场景。
信号量Semaphore,倒计时器CountDownLatch,以及同步执行器CyclicBarrier,它们各有其特定的萌小集淘宝客源码并发控制用途。原子类,如AtomicInteger,确保操作的不可分割性。ThreadLocal则为每个线程维护独立的局部变量副本,适用于线程独立数据的处理,但需注意内存泄漏问题。
最后,Thread类的方法如start()启动任务,run()执行操作,yield()让出CPU,join()等待线程结束,而stop()已被弃用。sleep()和isAlive()则是控制线程暂停和判断存活状态的工具。至于同步控制,wait(), notify(), notifyAll()在并发编程中发挥着至关重要的作用。
Java大厂面试道题( JUC篇)
Q1:什么是 CAS?
CAS 表示 Compare And Swap,比较并交换,需要三个操作数:内存位置 V、旧的预期值 A 和准备设置的新值 B。当且仅当 V 符合 A 时,处理器才会用 B 更新 V 的值,否则不执行更新。CAS 指令是原子操作,执行期间不会被其他线程打断。
CAS 操作由 JDK 5 后的 Java 类库使用,通过 Unsafe 类包装提供。HotSpot 对这些方法做了特殊处理,即时编译为处理器 CAS 指令。Unsafe 类不是用户程序调用的类,只有 Java 类库可以使用 CAS,如 AtomicInteger 的 compareAndSet 方法。
Q2:CAS 有什么问题?
CAS 存在逻辑漏洞,即 ABA 问题。初次读取 V 为 A,准备赋值时仍为 A,但期间 V 可能先改为 B 又改回 A,导致 CAS 错误地认为 V 未被改变。为解决此问题,juc 包提供了 AtomicStampedReference,通过版本号控制引用更新。
Q3:有哪些原子类?
JDK 5 提供了 java.util.concurrent.atomic 包,包括用于原子更新基本类型、数组、引用和字段的 个类。这些类提供了简单、高效、线程安全的变量更新方式。
原子类包括:AtomicInteger、AtomicLong、AtomicBoolean、AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray、AtomicReference、AtomicMarkableReference、AtomicStampedReference、AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater。
Q4:AtomicInteger 实现原理?
AtomicInteger 使用原子操作更新整型值。getAndIncrement 方法原子地将值加 1,使用 for 循环读取、加 1、原子更新值。如果值未被其他线程修改,则更新成功;否则失败并循环尝试。
atomic 包提供 CAS 方法,如 compareAndSwapInt,用于原子更新基本类型,如 Boolean 通过转整型实现。
Q5:CountDownLatch 是什么?
CountDownLatch 是基于时间的同步类,允许线程等待其他线程完成操作。构造方法接收计数器值,每次调用 countDown 减 1,await 方法阻塞线程至计数器为 0。n 个点可以是 n 个线程或步骤。
Q6:CyclicBarrier 是什么?
CyclicBarrier 是基于同步到达的信号触发机制,让一组线程到达屏障后被阻塞,直至最后一个线程到达解除屏障。适用于多线程任务协作,如计算数据合并。
CyclicBarrier 计数器可重置,支持在构造方法传入任务,适用于计算错误时重新计算。
Q7:Semaphore 是什么?
信号量控制线程访问公共资源的并发数,协调线程合理使用资源。可用于流量控制,如数据库连接。
Semaphore 通过 acquire 和 release 方法获取和释放许可。
Q8:Exchanger 是什么?
Exchanger 是线程间协作工具,用于数据交换。线程通过 exchange 方法交换数据,等待对方执行,交换数据后线程解除阻塞。
适用于遗传算法、校对工作等场景。
Q9:JDK7 ConcurrentHashMap 原理?
ConcurrentHashMap 使用分段锁降低冲突,每个数据段配一把锁,不同段数据并发访问。get 方法高效,直接定位并读取元素,无需加锁。put 必须加锁,进行元素添加,同时检查是否需要扩容。
size 方法统计元素数量,避免锁操作,通过 CAS 策略计算。
Q:JDK8 ConcurrentHashMap 原理?
JDK8 改进:取消分段锁,引入红黑树,元素数量超过阈值时链表转为树。优化元素数量统计,使用 CAS 替代锁。
get 和 put 操作使用 CAS,避免锁,当链表转树或树转回链表时,使用同步块保护当前元素。
Q:线程安全集合?
使用 CopyOnWriteArrayList 替代 ArrayList,读写分离,写操作复制新集合,修改后替换原集合引用,适合读多写少、单个添加效率低的场景。
CopyOnWriteArrayList 是 fail-safe 的,安全副本遍历,修改与遍历无关,但无法读取最新数据。
学习资源:《java学习指南》,包含学习资料、路线图、方法、面试技巧,全面的 Java 知识。
推荐学习课程:java基础Java 基础视频教程、尚学堂Java集零基础视频教程。