Java Thread类(线程)深度解析与实战应用指南

Thread类

  • 1. 什么是线程?
  • 2. 创建线程的三种方式
  • 方式一:继承 `Thread` 类
  • 特点:
  • 示例:
  • 方式二:实现 `Runnable` 接口
  • 特点:
  • 示例:
  • 方式三:使用 Lambda 表达式(推荐方式)
  • 特点:
  • 示例:
  • 3. `Thread` 类的重要方法
  • (1) 启动线程
  • (2) 获取/设置线程名称
  • (3) 线程休眠
  • (4) 线程合并
  • (5) 中断线程
  • (6) 检查线程状态
  • 4. 线程的生命周期
  • 5. 多线程中的问题及解决方法
  • (1) 线程安全问题
  • (2) 死锁问题
  • 6. 高级线程工具
  • Java中的
    Thread类是多线程编程的核心组件。

    1. 什么是线程?

  • 线程(Thread) 是程序执行的最小单位。一个Java程序默认至少有一个主线程,即main线程,负责执行main()方法。
  • 一个进程(Process) 可以包含多个线程,多个线程可以共享进程中的资源(如内存、文件句柄等)。
  • Java使用Thread类和Runnable接口来实现多线程编程。

  • 2. 创建线程的三种方式

    Java中创建线程主要有以下三种方式,每种方式有其适用场景。

    方式一:继承 Thread

    通过继承Thread类并重写run()方法实现线程逻辑。创建线程对象后,调用start()方法启动线程。

    特点:

  • 不适合需要继承其他类的场景(Java单继承限制)。
  • 更直接,适合简单的线程任务。
  • 示例:

    class MyThread extends Thread {
        @Override
        public void run() {
            // 线程执行的任务
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " - " + i);
            }
        }
    }
    
    public class ThreadExample {
        public static void main(String[] args) {
            MyThread thread1 = new MyThread();
            MyThread thread2 = new MyThread();
    
            thread1.start();  // 启动线程
            thread2.start();
        }
    }
    

    输出示例(结果不固定):

    Thread-0 - 0
    Thread-1 - 0
    Thread-0 - 1
    Thread-1 - 1
    ...
    

    方式二:实现 Runnable 接口

    通过实现Runnable接口,并将实现类的对象传递给Thread构造函数。

    特点:

  • 更灵活,适合需要继承其他类的场景。
  • 解耦线程逻辑与线程控制。
  • 示例:

    class MyRunnable implements Runnable {
        @Override
        public void run() {
            // 线程执行的任务
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " - " + i);
            }
        }
    }
    
    public class RunnableExample {
        public static void main(String[] args) {
            MyRunnable runnable = new MyRunnable();
            Thread thread1 = new Thread(runnable);
            Thread thread2 = new Thread(runnable);
    
            thread1.start();
            thread2.start();
        }
    }
    

    方式三:使用 Lambda 表达式(推荐方式)

    Java 8 引入了 Lambda 表达式,可以更简洁地定义线程任务。

    特点:

  • 简化代码,适合轻量级的线程任务。
  • 适用于实现Runnable接口的方式。
  • 示例:

    public class LambdaExample {
        public static void main(String[] args) {
            Thread thread1 = new Thread(() -> {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " - " + i);
                }
            });
    
            Thread thread2 = new Thread(() -> {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " - " + i);
                }
            });
    
            thread1.start();
            thread2.start();
        }
    }
    

    3. Thread 类的重要方法

    Java中的Thread类提供了丰富的方法,用于控制线程的执行行为。

    (1) 启动线程

    start():启动线程并调用其run()方法,开启线程的新执行路径。

    thread.start();
    

    注意: 不能直接调用run(),否则线程不会真正启动。

    (2) 获取/设置线程名称

    getName():获取线程名称。
    setName(String name):设置线程名称。

    示例:

    Thread thread = new Thread(() -> {
        System.out.println("线程名称:" + Thread.currentThread().getName());
    });
    
    thread.setName("MyThread");
    thread.start();
    

    (3) 线程休眠

    Thread.sleep(long millis):让当前线程暂停执行,进入休眠状态。

  • 单位为毫秒。
  • 休眠过程中线程不会释放锁。
  • 示例:

    try {
        System.out.println("线程休眠...");
        Thread.sleep(2000); // 休眠2秒
        System.out.println("休眠结束");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    (4) 线程合并

    join():等待一个线程执行完成。

    示例:

    Thread thread = new Thread(() -> {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    });
    
    thread.start();
    
    try {
        thread.join(); // 等待线程执行完成
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    
    System.out.println("子线程已完成");
    

    (5) 中断线程

    interrupt():中断线程(通知线程停止)。
    isInterrupted():检查线程是否被中断。

    示例:

    Thread thread = new Thread(() -> {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("线程正在运行...");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // 捕获中断异常并退出循环
                System.out.println("线程被中断");
                break;
            }
        }
    });
    
    thread.start();
    
    try {
        Thread.sleep(2000); // 主线程休眠2秒
        thread.interrupt(); // 中断子线程
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    (6) 检查线程状态

  • isAlive():检查线程是否仍在运行。
  • getState():获取线程的当前状态。

  • 4. 线程的生命周期

    线程的生命周期包括以下五种状态:

    1. 新建(NEW): 线程对象被创建,但未调用start()方法。
    2. 就绪(RUNNABLE): 线程调用start()方法,等待CPU调度。
    3. 运行(RUNNING): 线程被CPU调度并执行任务。
    4. 阻塞(BLOCKED/WAITING): 线程因某些操作(如锁、等待)暂停。
    5. 终止(TERMINATED): 线程执行完毕或被中断。
  • 也称新生就绪运行阻塞死亡
  • 示例:

    Thread thread = new Thread(() -> {});
    System.out.println(thread.getState()); // NEW
    thread.start();
    System.out.println(thread.getState()); // RUNNABLE
    

    5. 多线程中的问题及解决方法

    (1) 线程安全问题

    多个线程访问共享资源可能导致数据不一致。
    解决方法:使用同步机制(synchronized)。

    示例:

    class Counter {
        private int count = 0;
    
        public synchronized void increment() {
            count++;
        }
    
        public int getCount() {
            return count;
        }
    }
    
    public class SynchronizedExample {
        public static void main(String[] args) {
            Counter counter = new Counter();
    
            Thread t1 = new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    counter.increment();
                }
            });
    
            Thread t2 = new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    counter.increment();
                }
            });
    
            t1.start();
            t2.start();
    
            try {
                t1.join();
                t2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println("最终计数:" + counter.getCount());
        }
    }
    

    (2) 死锁问题

    多个线程因资源争用互相等待,导致无法继续执行。

    示例:

    class DeadlockExample {
        private final Object lock1 = new Object();
        private final Object lock2 = new Object();
    
        public void method1() {
            synchronized (lock1) {
                System.out.println(Thread.currentThread().getName() + " 获得锁1");
                synchronized (lock2) {
                    System.out.println(Thread.currentThread().getName() + " 获得锁2");
                }
            }
        }
    
        public void method2() {
            synchronized (lock2) {
                System.out.println(Thread.currentThread().getName() + " 获得锁2");
                synchronized (lock1) {
                    System.out.println(Thread.currentThread().getName() + " 获得锁1");
                }
            }
        }
    }
    
    public class DeadlockDemo {
        public static void main(String[] args) {
            DeadlockExample example = new DeadlockExample();
    
            Thread t1 = new Thread(example::method1);
            Thread t2 = new Thread(example::method2);
    
            t1.start();
            t2.start();
        }
    }
    

    解决方案:

  • 避免嵌套锁。
  • 使用锁的超时机制(如tryLock)。
  • 通过锁排序避免循环等待。

  • 6. 高级线程工具

    Java 提供了更高级的并发工具(java.util.concurrent包):

  • ExecutorService:线程池管理。
  • CountDownLatch:线程等待计数器。
  • Semaphore:限制线程并发数。
  • Future:获取线程任务结果。
  • 线程池示例:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class ThreadPoolExample {
        public static void main(String[] args) {
            ExecutorService executor = Executors.newFixedThreadPool(3);
    
            for (int i = 0; i < 5; i++) {
                executor.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + " 正在执行任务");
                });
            }
    
            executor.shutdown();
        }
    }
    

    作者:凭君语未可

    物联沃分享整理
    物联沃-IOTWORD物联网 » Java Thread类(线程)深度解析与实战应用指南

    发表回复