第2章
🧵 线程基础
掌握Java线程的创建、生命周期、优先级和中断机制等核心概念
学习目标
- 掌握Thread类的使用方法
- 理解Runnable接口的优势
- 熟悉线程的生命周期
- 学会线程优先级和守护线程的使用
- 掌握线程中断机制
Thread类详解
Thread类是Java中用于创建和管理线程的核心类。它提供了创建线程、控制线程执行、获取线程状态等功能。理解Thread类的使用是掌握Java并发编程的基础。
Thread类的构造方法
Thread()
创建一个新的线程对象,使用默认的线程名称。
Thread(String name)
创建一个新的线程对象,并指定线程名称。
Thread(Runnable target)
创建一个新的线程对象,指定要执行的Runnable任务。
创建线程的方式
方式一:继承Thread类
ThreadExample.java
public class ThreadExample extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadExample thread1 = new ThreadExample();
ThreadExample thread2 = new ThreadExample();
thread1.setName("线程1");
thread2.setName("线程2");
thread1.start();
thread2.start();
}
}
方式二:实现Runnable接口
RunnableExample.java
public class RunnableExample implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
RunnableExample task = new RunnableExample();
Thread thread1 = new Thread(task, "线程1");
Thread thread2 = new Thread(task, "线程2");
thread1.start();
thread2.start();
}
}
Runnable和Callable接口
Runnable接口是创建线程任务的标准方式,而Callable接口提供了更强大的功能,包括返回值和异常处理。
Runnable vs Thread
Runnable的优势
- 避免单继承限制
- 更好的代码复用性
- 任务与线程分离
- 更灵活的线程池使用
Thread的限制
- Java单继承限制
- 任务与线程耦合
- 代码复用性差
- 不利于线程池管理
Lambda表达式创建线程
LambdaThreadExample.java
public class LambdaThreadExample {
public static void main(String[] args) {
// 使用Lambda表达式创建线程
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Lambda线程: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 使用方法引用
Thread thread2 = new Thread(LambdaThreadExample::printNumbers);
thread1.start();
thread2.start();
}
public static void printNumbers() {
for (int i = 0; i < 5; i++) {
System.out.println("方法引用线程: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程生命周期
Java线程在其生命周期中会经历多个状态,理解这些状态及其转换条件对于编写正确的并发程序至关重要。
NEW (新建)
线程对象已创建,但尚未调用start()方法。
RUNNABLE (可运行)
线程正在JVM中执行,可能正在运行或等待CPU时间片。
BLOCKED (阻塞)
线程被阻塞,等待获取监视器锁。
WAITING (等待)
线程无限期等待另一个线程执行特定操作。
TIMED_WAITING (超时等待)
线程等待指定时间后自动返回。
TERMINATED (终止)
线程执行完毕或因异常退出。
线程状态演示
ThreadStateExample.java
public class ThreadStateExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
Thread.sleep(2000);
synchronized (ThreadStateExample.class) {
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("创建后: " + thread.getState()); // NEW
thread.start();
System.out.println("启动后: " + thread.getState()); // RUNNABLE
Thread.sleep(100);
System.out.println("睡眠中: " + thread.getState()); // TIMED_WAITING
thread.join();
System.out.println("结束后: " + thread.getState()); // TERMINATED
}
}
线程优先级和守护线程
线程优先级用于指示线程调度器应该优先执行哪些线程,而守护线程是在后台提供服务的线程。
线程优先级
优先级说明
- MIN_PRIORITY (1):最低优先级
- NORM_PRIORITY (5):默认优先级
- MAX_PRIORITY (10):最高优先级
优先级示例
ThreadPriorityExample.java
public class ThreadPriorityExample {
public static void main(String[] args) {
Thread highPriorityThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("高优先级线程: " + i);
}
});
Thread lowPriorityThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("低优先级线程: " + i);
}
});
highPriorityThread.setPriority(Thread.MAX_PRIORITY);
lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
lowPriorityThread.start();
highPriorityThread.start();
}
}
守护线程
守护线程特点
- 为其他线程提供服务
- 当所有非守护线程结束时,JVM会退出
- 垃圾回收器就是典型的守护线程
- 必须在start()之前设置
守护线程示例
DaemonThreadExample.java
public class DaemonThreadExample {
public static void main(String[] args) throws InterruptedException {
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("守护线程运行中...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
// 设置为守护线程
daemonThread.setDaemon(true);
daemonThread.start();
// 主线程睡眠3秒后结束
Thread.sleep(3000);
System.out.println("主线程结束");
// JVM会自动退出,守护线程也会结束
}
}
线程中断机制
线程中断是Java提供的一种协作式的线程取消机制。它不会强制终止线程,而是给线程发送一个中断信号,由线程自己决定如何响应。
中断相关方法
interrupt()
中断线程,设置中断标志位为true。
isInterrupted()
检查线程是否被中断,不清除中断状态。
interrupted()
检查当前线程是否被中断,并清除中断状态。
中断处理示例
ThreadInterruptExample.java
public class ThreadInterruptExample {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("工作中...");
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("收到中断信号,准备退出");
// 重新设置中断状态
Thread.currentThread().interrupt();
break;
}
}
System.out.println("线程结束");
});
worker.start();
// 主线程睡眠3秒后中断工作线程
Thread.sleep(3000);
worker.interrupt();
worker.join();
System.out.println("程序结束");
}
}