Java 并发编程

简介: 面试

21、在 Java 中 CycliBarriar 和 CountdownLatch 有什么区 别?

CyclicBarrier 可以重复使用,而 CountdownLatch 不能重复使用。 Java 的 concurrent 包里面的 CountDownLatch 其实可以把它看作一个计数器, 只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器, 也就是同时只能有一个线程去减这个计数器里面的值。 你可以向 CountDownLatch 对象设置一个初始的数字作为计数值,任何调用这个 对象上的 await()方法都会阻塞,直到这个计数器的计数值被其他的线程减为 0 为 止。 所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待 的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法 被重置。如果需要重置计数,请考虑使用 CyclicBarrier。 CountDownLatch 的一个非常典型的应用场景是:有一个任务想要往下执行,但 必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续 往下执行的任务调用一个 CountDownLatch 对象的 await()方法,其他的任务执 行完自己的任务后调用同一个 CountDownLatch 对象上的 countDown()方法, 这个调用 await()方法的任务将一直阻塞等待,直到这个 CountDownLatch 对象 的计数值减到 0 为止。 CyclicBarrier 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏 障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程 必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待 线程后可以重用,所以称它为循环 的 barrier。

22、什么是不可变对象,它对写并发应用有什么帮助?

不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即 对象属性值)就不能改变,反之即为可变对象(Mutable Objects)。 不可变对象的类即为不可变类(Immutable Class)。Java 平台类库中包含许多不可 变类,如 String、基本类型的包装类、BigInteger 和 BigDecimal 等。 不可变对象天生是线程安全的。它们的常量(域)是在构造函数中创建的。既然 它们的状态无法修改,这些常量永远不会变。不可变对象永远是线程安全的。 只有满足如下状态,一个对象才是不可变的; 它的状态不能在创建后再被修改; 所有域都是 final 类型;并且, 它被正确创建(创建期间没有发生 this 引用的逸出)。

23、什么是多线程中的上下文切换?

在上下文切换过程中,CPU 会停止处理当前运行的程序,并保存当前程序运行的 具体位置以便之后继续运行。从这个角度来看,上下文切换有点像我们同时阅读 几本书,在来回切换书本的同时我们需要记住每本书当前读到的页码。在程序中, 上下文切换过程中的“页码”信息是保存在进程控制块(PCB)中的。PCB 还经 常被称作“切换桢”(switchframe)。“页码”信息会一直保存到 CPU 的内存 中,直到他们被再次使用。 上下文切换是存储和恢复 CPU 状态的过程,它使得线程执行能够从中断点恢复执 行。上下文切换是多任务操作系统和多线程环境的基本特征。

24、Java 中用到的线程调度算法是什么?

计算机通常只有一个 CPU,在任意时刻只能执行一条机器指令,每个线程只有获得 CPU 的使用权才能执行指令.所谓多线程的并发运行,其实是指从宏观上看,各个线 程轮流获得 CPU 的使用权,分别执行各自的任务.在运行池中,会有多个处于就绪状 态的线程在等待 CPU,JAVA 虚拟机的一项任务就是负责线程的调度,线程调度是指 按照特定机制为多个线程分配 CPU 的使用权. 有两种调度模型:分时调度模型和抢占式调度模型。 分时调度模型是指让所有的线程轮流获得 cpu 的使用权,并且平均分配每个线程占 用的 CPU 的时间片这个也比较好理解。java 虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用 CPU,如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用 CPU。处于运行状态的线程会一直运行,直至它不得不放弃 CPU。

25、什么是线程组,为什么在 Java 中不推荐使用?

线程组和线程池是两个不同的概念,他们的作用完全不同,前者是为了方便线程 的管理,后者是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。

相关文章
|
2月前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
1月前
|
安全 Java 程序员
深入理解Java内存模型与并发编程####
本文旨在探讨Java内存模型(JMM)的复杂性及其对并发编程的影响,不同于传统的摘要形式,本文将以一个实际案例为引子,逐步揭示JMM的核心概念,包括原子性、可见性、有序性,以及这些特性在多线程环境下的具体表现。通过对比分析不同并发工具类的应用,如synchronized、volatile关键字、Lock接口及其实现等,本文将展示如何在实践中有效利用JMM来设计高效且安全的并发程序。最后,还将简要介绍Java 8及更高版本中引入的新特性,如StampedLock,以及它们如何进一步优化多线程编程模型。 ####
37 0
|
1月前
|
Java 程序员
Java编程中的异常处理:从基础到高级
在Java的世界中,异常处理是代码健壮性的守护神。本文将带你从异常的基本概念出发,逐步深入到高级用法,探索如何优雅地处理程序中的错误和异常情况。通过实际案例,我们将一起学习如何编写更可靠、更易于维护的Java代码。准备好了吗?让我们一起踏上这段旅程,解锁Java异常处理的秘密!
|
29天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
1月前
|
算法 Java 调度
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
66 12
|
29天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
160 2
|
2月前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
2月前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
1月前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
1月前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
66 3