线程基础

Java 多线程是 Java 编程中实现并发编程的核心技术,它允许程序同时执行多个任务,提高 CPU 利用率和程序性能。

基本概念

  1. 进程与线程

    • 进程:操作系统资源分配的基本单位
    • 线程:CPU 调度的基本单位,一个进程可以包含多个线程
  2. 线程状态

    • NEW(新建)
    • RUNNABLE(可运行)
    • BLOCKED(阻塞)
    • WAITING(等待)
    • TIMED_WAITING(定时等待)
    • TERMINATED(终止)

状态流转

stateDiagram-v2 [*] --> NEW NEW --> RUNNABLE: start() state RUNNABLE { [*] --> READY READY --> RUNNING: 获得CPU时间片 RUNNING --> READY: 时间片用完/yield() } RUNNABLE --> WAITING: wait()/join()/park() WAITING --> RUNNABLE: notify()/notifyAll()/unpark() RUNNABLE --> TIMED_WAITING: sleep(n)/wait(n)/join(n) TIMED_WAITING --> RUNNABLE: 超时结束 RUNNABLE --> BLOCKED: 等待锁 BLOCKED --> RUNNABLE: 获取到锁 RUNNABLE --> TERMINATED: run()执行完成 TERMINATED --> [*]
转换前状态 触发条件 转换后状态
NEW 调用 start() RUNNABLE
RUNNABLE 调用 wait()/join()/LockSupport.park() WAITING
RUNNABLE 调用 sleep(n)/wait(n)/join(n) TIMED_WAITING
RUNNABLE 尝试获取锁失败 BLOCKED
RUNNABLE run()方法执行完毕 TERMINATED
WAITING notify()/notifyAll()/LockSupport.unpark() RUNNABLE
TIMED_WAITING 等待时间结束 RUNNABLE
BLOCKED 获取到锁 RUNNABLE
  1. **RUNNABLE** 状态内部包含操作系统层面的「就绪(READY)」和「运行中(RUNNING)」两种子状态
  2. 从 **BLOCKED** 状态恢复必须由其他线程释放锁
  3. **TERMINATED** 是最终状态,不可逆转
  4. 调用 `yield()` 只会让线程从 RUNNING 回到 READY 状态(仍属于 RUNNABLE)

常用方法

1. 线程生命周期控制

方法 所属类/接口 说明 注意事项
start() Thread 启动线程,使线程进入RUNNABLE状态 只能调用一次,第二次调用会抛IllegalThreadStateException
run() Thread/Runnable 线程实际执行的代码 直接调用run()不会启动新线程
sleep(long millis) Thread 让当前线程休眠指定毫秒数 不释放锁
yield() Thread 提示调度器当前线程愿意让出CPU 只是提示,不保证生效
interrupt() Thread 中断目标线程 只是设置中断标志位,需配合isInterrupted()使用
isInterrupted() Thread 检查线程是否被中断 不清除中断状态
interrupted() Thread 检查并清除中断状态 静态方法,清除当前线程的中断状态

2. 线程同步方法

方法 所属类/接口 说明 注意事项
wait() Object 释放锁并进入WAITING状态 必须在同步块(synchronized)中调用
notify() Object 随机唤醒一个等待线程 必须在同步块中调用
notifyAll() Object 唤醒所有等待线程 必须在同步块中调用
join() Thread 等待目标线程终止 底层使用wait()实现
join(long millis) Thread 限时等待线程终止 超时后继续执行

创建线程的方式

1. 继承 Thread 类

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程运行中...");
    }
}

// 使用
MyThread thread = new MyThread();
thread.start();

2. 实现 Runnable 接口

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程运行中...");
    }
}

// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();

3. 实现 Callable 接口(可返回结果)

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "任务执行结果";
    }
}

// 配合 Thread
Thread thread = new Thread(new FutureTask<>());
thread.start();
String result1 = thread.get(); // 获取返回结果

// 配合线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
String result2 = future.get(); // 获取返回结果
executor.shutdown();

4. 线程池

Java 提供了 Executor 框架来管理线程池,线程池后面说

// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(10);

// 提交任务
executor.execute(new RunnableTask());
Future<String> future = executor.submit(new CallableTask());

// 关闭线程池
executor.shutdown();
posted @ 2024-07-24 22:33  CyrusHuang  阅读(14)  评论(0)    收藏  举报