Skip to content

18.1 线程概念

线程的概念

线程(Thread)是程序执行的最小单位,是进程中的一个独立执行路径。一个进程可以包含多个线程,这些线程共享进程的资源,但拥有各自的执行栈和程序计数器。

线程 vs 进程

特性进程线程
定义程序的一次执行过程进程中的一个执行单元
资源分配系统分配资源的基本单位不拥有系统资源,共享进程资源
独立性进程之间相互独立线程之间共享进程资源
通信进程间通信复杂(如管道、消息队列)线程间通信简单(如共享变量)
切换开销较大较小
数量系统中进程数量相对较少一个进程中可以有多个线程

线程的状态

Java 中的线程有以下几种状态:

  1. 新建(New):线程对象已创建,但尚未启动
  2. 运行(Runnable):线程正在执行,或等待 CPU 时间片
  3. 阻塞(Blocked):线程等待获取锁
  4. 等待(Waiting):线程等待其他线程的通知
  5. 超时等待(Timed Waiting):线程等待指定时间后自动唤醒
  6. 终止(Terminated):线程执行完毕或异常终止

线程的生命周期

线程的生命周期包括以下阶段:

  1. 创建:通过 new Thread() 创建线程对象
  2. 启动:调用 start() 方法启动线程
  3. 运行:线程执行 run() 方法中的代码
  4. 阻塞/等待:线程因某些原因暂时停止执行
  5. 终止:线程执行完毕或异常终止

线程的优势

  1. 提高程序响应速度:多线程可以同时处理多个任务,提高程序的响应速度

  2. 充分利用 CPU 资源:多线程可以充分利用 CPU 的多核资源

  3. 简化程序结构:将复杂的任务分解为多个线程,使程序结构更清晰

  4. 提高系统吞吐量:多线程可以同时处理多个请求,提高系统的吞吐量

线程的应用场景

  1. GUI 应用:后台处理任务,保持界面响应

  2. 服务器应用:同时处理多个客户端请求

  3. 批量处理:并行处理大量数据

  4. 实时应用:如游戏、实时监控等

示例:多线程的简单应用

java
public class ThreadExample {
    public static void main(String[] args) {
        // 创建线程
        Thread thread1 = new Thread(new MyRunnable(), "线程1");
        Thread thread2 = new Thread(new MyRunnable(), "线程2");
        
        // 启动线程
        thread1.start();
        thread2.start();
        
        // 主线程继续执行
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " 执行: " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " 执行: " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

线程的创建方式

Java 中创建线程有两种主要方式:

  1. 继承 Thread 类
java
public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的代码
    }
}

// 创建并启动线程
MyThread thread = new MyThread();
thread.start();
  1. 实现 Runnable 接口
java
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的代码
    }
}

// 创建并启动线程
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
  1. 使用 Lambda 表达式(Java 8+):
java
// 使用 Lambda 表达式创建线程
Thread thread = new Thread(() -> {
    // 线程执行的代码
});
thread.start();

线程的基本操作

  1. 启动线程start() 方法
  2. 暂停线程sleep(long millis) 方法
  3. 等待线程join() 方法
  4. 中断线程interrupt() 方法
  5. 获取线程状态getState() 方法
  6. 获取线程名称getName() 方法
  7. 设置线程名称setName(String name) 方法
  8. 获取当前线程Thread.currentThread() 方法

示例:线程的基本操作

java
public class ThreadOperationsExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("线程开始执行");
            try {
                // 暂停 2 秒
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                System.out.println("线程被中断");
            }
            System.out.println("线程执行完毕");
        }, "工作线程");
        
        // 启动线程
        thread.start();
        
        // 获取线程状态
        System.out.println("线程状态: " + thread.getState());
        
        // 等待线程执行完毕
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 获取线程状态
        System.out.println("线程状态: " + thread.getState());
    }
}

线程安全

什么是线程安全

线程安全是指多个线程同时访问共享资源时,不会导致数据不一致或其他意外结果的情况。

线程安全问题的原因

  1. 共享资源:多个线程同时访问同一个资源
  2. 非原子操作:操作不是原子的,可能被其他线程打断
  3. 可见性问题:一个线程对共享变量的修改,其他线程可能看不到
  4. 重排序问题:编译器或 CPU 可能对指令进行重排序

线程安全的解决方案

  1. 同步代码块:使用 synchronized 关键字
  2. 同步方法:使用 synchronized 修饰方法
  3. :使用 Lock 接口及其实现类
  4. 线程安全的集合:如 ConcurrentHashMap
  5. 原子类:如 AtomicInteger
  6. 线程本地存储:使用 ThreadLocal

示例:线程安全问题

java
public class ThreadSafetyExample {
    private static int count = 0;
    
    public static void main(String[] args) {
        // 创建 10 个线程,每个线程增加 count 1000 次
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    count++;
                }
            }).start();
        }
        
        // 等待所有线程执行完毕
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 打印结果
        System.out.println("最终 count 值: " + count);
        // 预期结果应该是 10000,但实际结果可能小于 10000
    }
}

示例:线程安全解决方案

java
public class ThreadSafetySolution {
    private static int count = 0;
    private static final Object lock = new Object();
    
    public static void main(String[] args) {
        // 创建 10 个线程,每个线程增加 count 1000 次
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    synchronized (lock) {
                        count++;
                    }
                }
            }).start();
        }
        
        // 等待所有线程执行完毕
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 打印结果
        System.out.println("最终 count 值: " + count);
        // 结果应该是 10000
    }
}

总结

线程是 Java 中实现并发编程的重要机制:

  1. 线程的概念:线程是程序执行的最小单位,是进程中的一个独立执行路径

  2. 线程 vs 进程:线程共享进程资源,切换开销小,通信简单

  3. 线程的状态:新建、运行、阻塞、等待、超时等待、终止

  4. 线程的生命周期:创建、启动、运行、阻塞/等待、终止

  5. 线程的优势:提高程序响应速度、充分利用 CPU 资源、简化程序结构、提高系统吞吐量

  6. 线程的创建方式:继承 Thread 类、实现 Runnable 接口、使用 Lambda 表达式

  7. 线程的基本操作:启动、暂停、等待、中断等

  8. 线程安全:多个线程同时访问共享资源时的安全问题及解决方案

通过合理使用线程,可以充分利用系统资源,提高程序的性能和响应速度。

© 2026 编程马·菜鸟教程 版权所有