Java多线程

1. 为什么使用多线程

  • 总体上说:
    • 从计算机底层来说:线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度成本远低于进程。且多核CPU可以减少线程上下文切换的开销
    • 从互联网发展趋势来说:多线程并发编程是开发高并发系统的基础
  • 深入到计算机底层讨论:
    • 单核时代:多线程主要是为了提高单进程的利用CPU和IO系统的效率
    • 多核时代:提高进程利用多核CPU的能力

2. 单核CPU支持多线程吗

  • 支持,使用时间片轮转的方式实现多线程
  • 操作系统主要是通过两种线程调度方式来管理多线程执行:
    • 抢占式调度(Preemptive Scheduling):操作系统决定何时暂停当前正在运行的线程,并切换到另一个线程执行。这种切换通常是由**系统时钟中断(时间片轮转)其他高优先级事件(如 I/O 操作完成)**触发的。这种方式存在上下文切换开销,但公平性和 CPU 资源利用率较好,不易阻塞。
    • 协同式调度(Cooperative Scheduling):线程执行完毕后,主动通知系统切换到另一个线程。这种方式可以减少上下文切换带来的性能开销,但公平性较差,容易阻塞。
  • Java使用的线程调度是抢占式的,JVM本身不负责线程的调度,而是将线程的调度委托给操作系统。操作系统通常会基于线程优先级和时间片来调度线程的执行,高优先级的线程通常获得CPU时间片的机会更多

3. 单核CPU上运行多个线程效率一定会高吗

  • 不一定,取决于线程的类型和任务的性质
  • 一般来说,有两种类型的线程:
    • CPU密集型:主要进行计算和逻辑处理,需要占用大量的CPU资源
    • IO密集型:主要进行IO操作,如文件读写、网络通信等,CPU资源占用较少
  • 在单核CPU上运行多个线程时:
    • 对于CPU密集型任务:多个线程会争夺CPU资源,频繁的线程切换会带来较大的上下文切换开销,反而可能降低整体效率
    • 对于IO密集型任务:线程在等待IO操作完成时会释放CPU资源,其他线程可以利用这些空闲时间执行任务,从而提高整体效率