Skip to content

Java 并发编程基础

Java 并发编程是 Java 开发中非常重要的一部分,尤其是在多核 CPU 普及的今天,合理利用多线程可以显著提高程序的性能。

并发与并行的区别

并发(Concurrency)

并发是指多个任务在同一时间段内交替进行,从宏观的角度上看像是同时进行,但实际上是通过时间片轮转的方式交替执行。

在单核 CPU 中运行多个线程时,CPU 通过快速切换线程的方式实现并发。

并发可以提高系统的吞吐量,但不能提高单个任务的执行速度,并且可以提高资源利用率,使多个任务能够“同时”进行。

并行(Parallelism)

并行是指多个任务在同一时刻真正同时执行,通常需要多核 CPU 的支持。

在多核 CPU 上,每个核心可以独立执行一个线程,从而实现真正的并行。

并行可以提高任务执行速度,缩短整体运行的时间。

多核 CPU 与多线程的关系

  1. 多核 CPU 为并行计算提供了硬件支持,每个核心可以独立运行一个线程。
  2. 多线程编程可以充分利用多核 CPU 的计算能力,将任务分配到多个核心上并行执行。
  3. 并发编程的目标是编写能够同时处理多个任务的程序,而并行是实现并发的一种手段。

线程的基本概念

什么是线程?

线程是操作系统调度的最小单位,是进城中的一个执行流。

一个进程可以包含多个线程,线程之间共享进程的内存空间(堆、方法区),但每个线程有自己的栈和程序计数器。

线程是轻量级的,创建和切换线程的开销比进程小。

线程的生命周期

线程的生命周期包含以下几个状态:

  1. 新建(New):线程对象被创建,但尚未调用 start() 方法。
  2. 就绪(Runnable):线程调用 start() 方法后,等待 CPU 调度。
  3. 运行(Running):线程获得 CPU 时间片,正在执行 run() 方法。
  4. 阻塞(Blocked):线程因为某种原因(如等待锁、I/O 操作等)暂时停止执行。
  5. 终止(Terminated):线程执行完 run() 方法,或者因异常退出。

线程的创建方式

  1. 继承 Thread 类。

定义一个类继承 Thread 类,并重写 run() 方法。

java
class MyThread extends Thread {
  @Override
  public void run() {
      System.out.println("Thread is running");
  }
}
MyThread thread = new MyThread();
thread.start();
  1. 实现 Runnable 接口。

定义一个类实现 Runnable 接口,并实现 run() 方法。

java
class MyRunnable implements Runnable {
  @Override
  public void run() {
      System.out.println("Thread is running");
  }
}
Thread thread = new Thread(new MyRunnable());
thread.start();
  1. 实现 Callable 接口。
  • CallableRunnable 类似,但可以返回结果或抛出异常。

  • 需要配合 FutureTask 或线程池使用。

    java
    class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "Thread is running";
        }
    }
    FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
    Thread thread = new Thread(futureTask);
    thread.start();
    System.out.println(futureTask.get()); // 获取返回值

线程的启动、暂停、中断和终止

  1. 启动:调用 start() 方法,线程进入就绪状态。
  2. 暂停:使用 sleep() 方法让线程暂停一段时间。
  3. 中断:调用 interrupt() 方法中断线程。
  4. 终止:线程执行完 run() 方法或抛出未捕获的异常时终止。

线程的基本操作

常用方法

  1. start():启动线程,使其进入就绪状态。
  2. run():线程的执行逻辑,需要重写。
  3. join():等待线程执行完毕。
java
Thread thread = new Thread(() -> System.out.println("Thread is running"));
thread.start();
thread.join(); // 主线程等待 thread 执行完毕
  1. sleep(long millis):让当前线程暂停指定时间(毫秒)。
java
Thread.sleep(1000); // 暂停 1 秒
  1. yield():让出 CPU 时间片,使当前线程进入就绪状态,让其他线程有机会执行。

线程的中断机制

  • interrupt():终端线程,设置线程的中断标志。
  • isInterrupted():检查线程是否被中断。
  • interrupted():检查线程是否被中断,并清除中断标志。
java
Thread thread = new Thread(() -> {
    while (!Thread.currentThread().isInterrupted()) {
        System.out.println("Thread is running");
    }
});
thread.start();
Thread.sleep(1000);
thread.interrupt(); // 中断线程

线程的优先级

线程优先级的设置与作用

线程优先级是一个整数,范围从 1(最低)到 10(最高),默认为 5。

在下方示例中,展示了如何设置线程优先级:

java
Thread thread = new Thread(() -> System.out.println("Thread is running"));
thread.setPriority(Thread.MAX_PRIORITY); // 设置为最高优先级
thread.start();

优先级对线程调用的影响

  • 优先级高的线程有更大机会被 CPU 调度执行。
  • 但优先级并不能保证线程的执行顺序,具体调度取决于操作系统的实现。

总结

  • 并发是多个任务交替执行,并行是多个任务同时执行。
  • 线程是程序执行的基本单位,可以通过继承 Thread 类、实现 Runnable 接口或 Callable 接口创建线程。
  • 线程的生命周期包括:创建、就绪、运行、阻塞和终止。
  • 线程的基本操作包括:启动、暂停、中断和终止。
  • 线程的优先级可以影响线程的调度,但不能完全控制执行顺序。
编程洪同学服务平台是一个广泛收集编程相关内容和资源,旨在满足编程爱好者和专业开发人员的需求的网站。无论您是初学者还是经验丰富的开发者,都可以在这里找到有用的信息和资料,我们将助您提升编程技能和知识。
专业开发
高端定制
售后无忧
站内资源均为本站制作或收集于互联网等平台,如有侵权,请第一时间联系本站,敬请谅解!本站资源仅限于学习与参考,严禁用于各种非法活动,否则后果自行负责,本站概不承担!