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 中不推荐使用?
线程组和线程池是两个不同的概念,他们的作用完全不同,前者是为了方便线程 的管理,后者是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。