Java:Thread类(线程)

168°C 05-01-2025 notbyai
最近更新于:2025-01-05 21:26:02

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();
    }
}

评论留言

欢迎您,!您可以在这里畅言您的的观点与见解!

0 条评论