1. Java 线程概述
1.1 映射模型
Java 线程采用1:1映射到操作系统原生线程(内核级线程),线程是程序执行的一个路径,每一个钱程都有自己的局部变量表、程序计数器以及各自的生命周期等。在 JVM 中:
java.lang.Thread
对象是Java层的线程抽象- 底层通过
pthread_create
(Linux)或CreateThread
(Windows)创建系统线程 - 线程调度由操作系统内核直接管理(抢占式调度,时间片)
1.2 Java 多线程
现代操作系统中一般不止一个线程在运行,当启动了一个 Java 虚拟机时,从操作系统开始就会创建一个新的进程( JVM 进程),JVM 进程中将会派生或者创建很多线程,可以说 java 中的程序天生就是多线程:
java
// JDK 21
public class Test {
public static void main(String[] args) {
// Java 虚拟机线程系统的管理接口
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 获取线程和线程堆栈信息
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
for (ThreadInfo threadInfo :
threadInfos) {
System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
}
}
}
Java ThreadMXBean
是 Java Management Extensions(JMX)API 中的一个接口,用于管理和监控Java虚拟机的线程系统。
运行结果:

在 android 中可以使用以下代码打印:
java
public static void logAllThreads() {
try {
ThreadGroup group = Thread.currentThread().getThreadGroup();
// 遍历到最顶层的线程组
while (group.getParent() != null) {
group = group.getParent();
}
// 获取线程组中的线程数量
int threadCount = group.activeCount();
Thread[] threads = new Thread[threadCount];
group.enumerate(threads);
// 打印线程信息
for (Thread thread : threads) {
Log.i("ThreadInfo" + "[" + thread.getId() + "] " + thread.getName());
}
} catch (Exception e) {
Log.i("ThreadInfo" + "Error enumerating threads", e);
}
}

1.3 Java 线程状态
Java 线程状态在 Thread.State 中明确定义:
状态 | 触发条件 | 操作系统映射 |
---|---|---|
NEW | Thread实例化后,start()前 | 未创建系统线程 |
RUNNABLE | start()调用后 | 就绪/运行状态 |
BLOCKED | 竞争synchronized锁失败 | 内核阻塞状态 |
WAITING | wait()/join()/park()调用 | 内核休眠+条件等待 |
TIMED_WAITING | sleep(n)/wait(n)等超时方法 | 内核定时休眠 |
TERMINATED | run()执行结束 | 线程资源已回收 |
关键差异:Java的RUNNABLE状态对应操作系统的就绪(Ready)和运行(Running)两种状态
2. 多线程的实现方式
java 1.8 中写到,创建线程有两种方式。There are two ways to create a new thread of execution.
2.1 继承 Thread 类并实现 run 方法
声明一个 Thread 的子类,此子类应重写 Thread 类的 run 方法。
java
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
创建一个实例并运行:
java
PrimeThread p = new PrimeThread(143);
p.start();
优点:
- 编程比较简单
- 可以直接使用 Thread 类中的方法
缺点:
- 可扩展性差,耦合度高,不能再继承其他的类
- run 方法没有返回值,不能获取返回结果
2.2 声明一个实现 Runnable 接口的类并实现 run() 方法
Thread:对线程的抽象。
Runnable:对线程中任务、业务逻辑的抽象
Runnable 接口: 只有一个 run() 方法,当使用 Runnable 接口创建Thread 实例时,run() 方法被调用,该方法为线程执行的起点。
java
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
扩展性强,实现接口还可以继承其他类。
java
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
创建一个实例并运行:
java
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
使用内部类:
java
new Thread(new Runnable(){
@Override
public void run(){
//处理具体的逻辑
}
}).start();
优点:
- 实现接口还可以继承其他类
- 任务与线程解耦,支持线程池
- 策略模式的应用(点击阅读:策略模式)
缺点:
- run 方法没有返回值,不能获取返回结果。
2.3 利用 Callable 接口和 Future 接口方式实现
除了官方注释中给出的方法,我们还可以通过以下几种方法实现 java 线程。
实现 Callable 接口可以获取到多线程运行的结果。
java
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
sum = sum + i;
}
return sum;
}
}
//创建MyCallable对象(线程要执行的任务)
MyCallable mc = new MyCallable();
//创建FutureTask对象(管理多线程运行的结果)
FutureTask<Integer> ft = new FutureTask<>(mc);
Thread thread = new Thread(ft);
thread.start();
//获取多线程运行的结果
Integer result = ft.get();
System.out.println(result);
优点:
- 支持返回值与异常传播
java
FutureTask task = new FutureTask(() -> {
if(error) throw new IOException("模拟错误");
return 42;
});
new Thread(task).start();
try {
Integer result = task.get(); // 阻塞获取结果
} catch (ExecutionException e) {
Throwable cause = e.getCause(); // 获取原始异常
System.out.println("业务异常: " + cause.getMessage());
}
2.4 线程池
java
ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor(); // JDK21虚拟线程池
// Executors.newFixedThreadPool(10); // 传统固定池
pool.submit(() -> {
System.out.println(Thread.currentThread().getName());
});
核心优势:
- 降低线程创建销毁开销(线程复用)
- 提供队列缓冲(避免资源耗尽)
- 支持定时/周期任务
2.5 java21 中创建线程的方式
java
// Start a daemon thread to run a task
Thread thread = Thread.ofPlatform().daemon().start(runnable);
// Create an unstarted thread with name "duke", its start() method
// must be invoked to schedule it to execute.
Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);
// A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();
// Start a virtual thread to run a task
Thread thread = Thread.ofVirtual().start(runnable);
// A ThreadFactory that creates virtual threads
ThreadFactory factory = Thread.ofVirtual().factory();
2.6 总结
方式 | 代码示例 | 优势 | 劣势 | 原理 |
---|---|---|---|---|
继承Thread | class MyThread extends Thread { run(){...} } |
直接访问线程方法 | 破坏单一继承原则 | 创建OS线程绑定Java线程对象 |
实现Runnable | new Thread(() -> {...}).start() |
任务线程解耦 | 无返回值 | 策略模式:Thread组合Runnable |
Callable+Future | FutureTask task = new FutureTask(callable); new Thread(task).start() |
支持返回值/异常 | 编码较复杂 | FutureTask实现RunnableFuture接口 |
线程池提交 | executor.submit(() -> { return 42; }) |
资源复用/管理 | 需关闭线程池 | 线程复用+任务队列管理 |
本文简单描述一下 Java 线程的创建方式,后会不断深入分析补充