你想要了解 Java 中单线程和多线程的具体区别,并通过实际的代码例子来直观理解它们的执行方式,对吧?
下面我会分别提供单线程和多线程的完整代码示例,并详细解释它们的执行逻辑和差异,让你能清晰地看到两者的核心区别。
一、单线程示例
单线程程序中,代码会按照顺序从头到尾依次执行,只有前一个任务完成,后一个任务才会开始。
java
运行
/**
* 单线程示例:所有任务按顺序执行
*/
public class SingleThreadExample {
public static void main(String[] args) {
// 记录程序开始时间
long startTime = System.currentTimeMillis();
// 任务1:模拟耗时操作(比如计算)
System.out.println("开始执行任务1...");
for (int i = 0; i < 1000000000; i++) {
// 空循环模拟耗时计算
}
System.out.println("任务1执行完成!");
// 任务2:模拟另一个耗时操作
System.out.println("开始执行任务2...");
for (int i = 0; i < 1000000000; i++) {
// 空循环模拟耗时计算
}
System.out.println("任务2执行完成!");
// 计算总耗时
long endTime = System.currentTimeMillis();
System.out.println("单线程总耗时:" + (endTime - startTime) + " 毫秒");
}
}
执行结果(示例):
plaintext
开始执行任务1...
任务1执行完成!
开始执行任务2...
任务2执行完成!
单线程总耗时:800 毫秒
核心解释:
主线程(main 线程)是唯一的执行线程,任务 1 必须完全执行完,任务 2 才会开始。
总耗时约等于任务 1 耗时 + 任务 2 耗时。
二、多线程示例
多线程程序中,多个任务可以并发(宏观上同时)执行,多个线程各自独立运行,互不阻塞。
java
运行
/**
* 多线程示例:多个任务并发执行
*/
public class MultiThreadExample {
// 定义一个耗时任务的线程类
static class TaskThread extends Thread {
private String taskName;
public TaskThread(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
// 线程的核心执行逻辑
System.out.println("开始执行" + taskName + "...");
long startTime = System.currentTimeMillis();
// 模拟耗时操作
for (int i = 0; i < 1000000000; i++) {
// 空循环模拟耗时计算
}
long endTime = System.currentTimeMillis();
System.out.println(taskName + "执行完成!耗时:" + (endTime - startTime) + " 毫秒");
}
}
public static void main(String[] args) {
// 记录程序开始时间
long mainStartTime = System.currentTimeMillis();
// 创建两个线程
Thread thread1 = new TaskThread("任务1");
Thread thread2 = new TaskThread("任务2");
// 启动线程(注意:是start()不是run(),start()才会创建新线程)
thread1.start();
thread2.start();
// 等待两个线程都执行完成(避免主线程先结束)
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 计算总耗时
long mainEndTime = System.currentTimeMillis();
System.out.println("多线程总耗时:" + (mainEndTime - mainStartTime) + " 毫秒");
}
}
执行结果(示例):
plaintext
开始执行任务1...
开始执行任务2...
任务2执行完成!耗时:400 毫秒
任务1执行完成!耗时:405 毫秒
多线程总耗时:410 毫秒
核心解释:
start() 方法会创建新的线程,线程的执行逻辑在 run() 方法中。
任务 1 和任务 2 会并发执行(宏观上同时跑),总耗时约等于耗时最长的那个任务的时间,而不是两者相加。
join() 方法的作用是让主线程等待子线程执行完毕,否则主线程可能会先输出 “总耗时”,导致结果不准确。
三、关键补充:线程的另一种创建方式(Runnable 接口)
除了继承 Thread 类,更推荐实现 Runnable 接口(因为 Java 单继承的限制),效果完全一样:
java
运行
/**
* 实现Runnable接口的多线程示例(推荐方式)
*/
public class RunnableExample {
static class Task implements Runnable {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
System.out.println("开始执行" + taskName + "...");
// 模拟耗时操作
for (int i = 0; i < 1000000000; i++) {}
System.out.println(taskName + "执行完成!");
}
}
public static void main(String[] args) {
// 创建Runnable任务
Runnable task1 = new Task("任务1");
Runnable task2 = new Task("任务2");
// 包装成Thread并启动
new Thread(task1).start();
new Thread(task2).start();
}
}
总结
单线程:代码串行执行,任务按顺序完成,总耗时 = 各任务耗时之和,适用于简单、无耗时操作的场景。
多线程:任务并发执行,总耗时≈最长任务耗时,适用于有耗时操作(如 IO、计算、网络请求)的场景,能充分利用 CPU 资源。
核心方法:启动线程用 start()(创建新线程),不要直接调用 run()(只是普通方法调用,不会创建新线程);join() 可让主线程等待子线程完成。