Java作为广泛使用的后端开发语言,内置了丰富的线程类库来支持多线程编程,开发者可以通过这些类库快速实现并发任务处理,提升程序的资源利用率和响应速度。不同的线程类库适用于不同的开发场景,合理选择才能写出高效稳定的多线程代码。

Java常用线程类库介绍
1. Thread类
Thread是Java中最基础的线程类,位于java.lang包下,所有线程对象都基于该类或其子类创建。开发者可以通过继承Thread类并重写run方法来定义线程执行的任务逻辑。
以下是继承Thread类实现多线程的简单示例:
// 自定义线程类继承Thread
class MyThread extends Thread {
@Override
public void run() {
// 线程执行的逻辑
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " 执行次数:" + i);
try {
// 线程休眠100毫秒
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
// 创建两个线程对象
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
// 启动线程
thread1.start();
thread2.start();
}
}
2. Runnable接口
Runnable是Java提供的线程任务接口,位于java.lang包下,内部仅定义了一个无返回值的run方法。相比继承Thread类,实现Runnable接口可以避免单继承的限制,更适合需要复用任务逻辑的场景。
实现Runnable接口的多线程示例:
// 实现Runnable接口定义任务
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " 执行任务:" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
// 创建任务对象
MyRunnable runnable = new MyRunnable();
// 将任务传入Thread构造器创建线程
Thread thread1 = new Thread(runnable, "线程A");
Thread thread2 = new Thread(runnable, "线程B");
thread1.start();
thread2.start();
}
}
3. Callable接口与Future
Callable接口位于java.util.concurrent包下,和Runnable类似都是定义线程任务的接口,但Callable的call方法可以有返回值,并且可以抛出异常,适合需要获取线程执行结果的场景。Future接口则用来接收Callable任务的返回结果,通过Future的get方法可以阻塞获取结果。
Callable与Future的使用示例:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
// 实现Callable接口定义有返回值的任务
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
Thread.sleep(50);
}
return sum;
}
}
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建Callable任务
MyCallable callable = new MyCallable();
// 用FutureTask包装Callable任务
FutureTask<Integer> futureTask = new FutureTask<>(callable);
// 创建线程执行任务
Thread thread = new Thread(futureTask);
thread.start();
// 获取任务执行结果
Integer result = futureTask.get();
System.out.println("1到10的求和结果:" + result);
}
}
4. 线程池相关类库
频繁创建和销毁线程会带来较大的性能开销,Java在java.util.concurrent包中提供了线程池相关的类库,包括Executor接口、ExecutorService接口、Executors工具类等,通过线程池可以复用线程,控制并发线程数量,提升系统稳定性。
常用线程池使用示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建固定大小的线程池,容量为3
ExecutorService executorService = Executors.newFixedThreadPool(3);
// 提交10个任务到线程池
for (int i = 0; i < 10; i++) {
int taskId = i;
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName() + " 执行任务:" + taskId);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池,不再接收新任务,等待已有任务执行完成
executorService.shutdown();
}
}
多线程编程的注意事项
线程安全问题
当多个线程同时操作共享资源时,可能会出现数据不一致的问题,需要通过同步机制保证线程安全。常用的同步方式有使用synchronized关键字修饰方法或代码块,或者使用java.util.concurrent包下的Lock接口实现类如ReentrantLock。
以下是使用synchronized解决线程安全问题的示例:
public class SafeCounter {
private int count = 0;
// 使用synchronized修饰方法,保证同一时间只有一个线程能执行该方法
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
SafeCounter counter = new SafeCounter();
// 创建两个线程同时执行自增操作
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();
// 等待两个线程执行完成
t1.join();
t2.join();
System.out.println("最终计数结果:" + counter.getCount());
}
}
线程通信
多个线程之间可能需要协调执行顺序,Java提供了wait、notify、notifyAll方法来实现线程通信,这些方法需要在同步代码块或同步方法中调用。另外也可以使用java.util.concurrent包下的Condition接口实现更灵活的线程通信。
线程状态管理
Java线程有新建、就绪、运行、阻塞、死亡五种状态,开发者需要合理管理线程状态,避免线程长时间阻塞导致资源浪费,同时不要频繁强制中断线程,而是通过设置标志位等优雅方式停止线程。
总结
Java的线程类库覆盖了从基础线程创建到高级线程池管理的全场景需求,开发者可以根据任务是否需要返回值、是否需要复用逻辑、是否需要控制并发数等需求选择合适的类库。在多线程编程中,需要重点关注线程安全和线程通信问题,合理使用同步机制和线程管理方案,才能写出高效稳定的并发程序。