线程的创建方式与生命周期
线程是 Java 并发编程的基础单元。本文系统讲解线程的创建、状态和生命周期管理。
线程的三种创建方式
1. 继承 Thread 类
public class MyThread extends Thread { @Override public void run() { System.out.println("线程执行: " + Thread.currentThread().getName()); } }
MyThread thread = new MyThread(); thread.start();
|
缺点:Java 单继承限制,无法继承其他类。
2. 实现 Runnable 接口
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("线程执行: " + Thread.currentThread().getName()); } }
Thread thread = new Thread(new MyRunnable()); thread.start();
Thread thread2 = new Thread(() -> System.out.println("线程执行")); thread2.start();
|
优点:解耦任务和线程,更灵活。
3. 实现 Callable 接口
public class MyCallable implements Callable<String> { @Override public String call() throws Exception { Thread.sleep(1000); return "任务完成"; } }
FutureTask<String> futureTask = new FutureTask<>(new MyCallable()); new Thread(futureTask).start();
String result = futureTask.get(); System.out.println(result);
|
特点:可以返回值,可以抛出异常。
三种方式对比
| 方式 |
返回值 |
异常 |
灵活性 |
| Thread |
无 |
内部处理 |
低 |
| Runnable |
无 |
内部处理 |
高 |
| Callable |
有 |
可抛出 |
高 |
线程的六种状态
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED }
|
状态转换图
NEW -> start() -> RUNNABLE <-> 获取锁失败 -> BLOCKED -> 获取锁 -> RUNNABLE | |-> wait() -> WAITING -> notify()/notifyAll() -> RUNNABLE | |-> sleep(time)/wait(time)/join(time) -> TIMED_WAITING -> 时间到 -> RUNNABLE | |-> 执行完毕/异常 -> TERMINATED
|
各状态详解
NEW(新建)
Thread t = new Thread(() -> {}); System.out.println(t.getState());
|
线程被创建,未调用 start()。
RUNNABLE(可运行)
Thread t = new Thread(() -> { while (true) {} }); t.start(); System.out.println(t.getState());
|
包含操作系统层面的 Running 和 Ready 状态。
BLOCKED(阻塞)
Object lock = new Object();
Thread t1 = new Thread(() -> { synchronized (lock) { try { Thread.sleep(10000); } catch (InterruptedException e) {} } });
Thread t2 = new Thread(() -> { synchronized (lock) { } });
t1.start(); t2.start(); Thread.sleep(100); System.out.println(t2.getState());
|
等待获取监视器锁(synchronized)。
WAITING(等待)
Object lock = new Object();
Thread t = new Thread(() -> { synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) {} } });
t.start(); Thread.sleep(100); System.out.println(t.getState());
|
无限期等待,需要被唤醒:
Object.wait()
Thread.join()
LockSupport.park()
TIMED_WAITING(限时等待)
Thread t = new Thread(() -> { try { Thread.sleep(10000); } catch (InterruptedException e) {} });
t.start(); Thread.sleep(100); System.out.println(t.getState());
|
限时等待,时间到自动恢复:
Thread.sleep(long)
Object.wait(long)
Thread.join(long)
LockSupport.parkNanos(long)
LockSupport.parkUntil(long)
TERMINATED(终止)
Thread t = new Thread(() -> {}); t.start(); t.join(); System.out.println(t.getState());
|
线程执行完毕或异常退出。
线程基本操作
启动与中断
Thread t = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } });
t.start();
t.interrupt();
|
等待与通知
Object lock = new Object(); boolean flag = false;
Thread waiter = new Thread(() -> { synchronized (lock) { while (!flag) { try { lock.wait(); } catch (InterruptedException e) {} } System.out.println("条件满足,继续执行"); } });
Thread notifier = new Thread(() -> { synchronized (lock) { flag = true; lock.notifyAll(); } });
|
守护线程
Thread daemon = new Thread(() -> { while (true) { System.out.println("守护线程运行中..."); try { Thread.sleep(1000); } catch (InterruptedException e) {} } }); daemon.setDaemon(true); daemon.start();
|
特点:
- 后台服务线程(如垃圾回收线程)
- 所有非守护线程结束后,JVM 自动退出
- 守护线程不能持有需要关闭的资源
线程优先级
Thread t = new Thread(() -> {}); t.setPriority(Thread.MAX_PRIORITY);
|
注意:优先级只是提示,具体调度取决于操作系统,不可靠。
最佳实践
- 优先使用 Runnable/Callable:解耦任务和线程
- 正确响应中断:不要忽略 InterruptedException
- 使用线程池:不要直接创建 Thread
- 避免使用 stop/suspend/resume:已废弃,不安全
- 守护线程不持有资源:防止资源泄漏
ExecutorService executor = Executors.newFixedThreadPool(10); Future<String> future = executor.submit(() -> { return "任务结果"; }); String result = future.get(); executor.shutdown();
|
总结
理解线程的生命周期和状态转换是并发编程的基础。在实际开发中,应尽量使用线程池和并发工具类,避免直接操作 Thread 对象。