多线程基础
2026/8/24大约 2 分钟
多线程基础
Java 中创建多线程的三种方式,以及 Thread 与 Runnable 的核心区别。
创建线程的三种方式
1. 继承 Thread 类
class MyThread extends Thread {
public void run() {
// 线程执行体
}
}
new MyThread().start();2. 实现 Runnable 接口(推荐)
class MyThread implements Runnable {
public void run() {
// 线程执行体
}
}
MyThread my = new MyThread();
new Thread(my).start();3. 实现 Callable 接口(Java 5+,可返回结果)
class MyTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 100; // 执行结束产生返回值
}
}
ExecutorService service = Executors.newFixedThreadPool(10);
Future<Integer> future = service.submit(new MyTask());
int sum = future.get(); // 获取结果为什么优先使用 Runnable
- 避免 Java 单继承带来的局限(继承 Thread 后无法再继承其他类)
- 增强程序健壮性,代码可被多个线程共享,代码与数据独立
- 适合多个线程处理同一资源的场景
卖票示例:两种方式的差异
继承 Thread:每次 new MyThread().start() 都创建独立对象,每个线程各自执行自己的代码,各自卖 5 张票。
实现 Runnable:多个 Thread 共享同一个 Runnable 对象,共同完成任务(3 个线程共卖 5 张票)。
class MyThread implements Runnable {
private int ticket = 5; // 被多个线程共享
public void run() {
if (ticket > 0) {
System.out.println("ticket = " + ticket--);
}
}
}注意:共享资源需要同步
共享 Runnable 对象时可能产生线程不安全:一个线程判断 ticket > 0 后还没来得及减 1,另一个线程已把 ticket 减为 0,前者再减得到 -1。因此共享数据需要加同步(互斥锁),确保同一时刻只有一个线程执行操作。
public synchronized void run() {
if (ticket > 0) {
System.out.println("ticket = " + ticket--);
}
}wait() 与 sleep() 的区别
| 对比项 | sleep() | wait() |
|---|---|---|
| 所属类 | Thread 静态方法 | Object 方法 |
| 是否释放锁 | 不释放对象锁,监控状态保持 | 释放对象锁,进入等待池 |
| 恢复方式 | 到时自动恢复(就绪态) | 需 notify/notifyAll 唤醒 |
| 用途 | 暂停指定时间 | 线程间通信 |