第2章

🧵 线程基础

掌握Java线程的创建、生命周期、优先级和中断机制等核心概念

学习目标

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("程序结束");
    }
}
上一章:并发编程基础 返回目录 下一章:synchronized关键字