在前面的文章中,我们介绍了多线程(Java进阶篇之多线程)。在开发高效的并发应用时,线程的创建与运行是我们需要掌握的基本技能。线程能够让我们同时处理多个任务,充分利用多核 CPU 提高程序的执行效率。Java 提供了多种方式来创建和启动线程,从简单的继承 Thread
类到实现 Runnable
接口,再到使用现代的 ExecutorService
,每种方式都有其适用的场景。
今天,我们就来聊一聊 Java 中线程的创建与运行,如何在不同的场景下灵活运用这些方式,提升你的多线程编程水平,让你的程序更快、更高效!
目录
引言
一、线程的基础概念
线程的生命周期 ⏳
二、线程的创建与运行方式 ♂️
1️⃣ 继承 Thread 类
2️⃣ 实现 Runnable 接口 ♂️
3️⃣ 使用 ExecutorService 线程池 ️
三、线程的优先级 ⚖️
四、线程的常见问题与调试
1️⃣ 线程安全
2️⃣ 死锁
3️⃣ 线程饥饿与活锁
五、总结
思维导图
在 Java 中,线程 是程序执行的最小单位。线程有自己的运行环境,如独立的栈和程序计数器。多个线程共享堆内存数据,每个线程都有自己的执行路径。
main
方法执行的线程。线程的生命周期有几个状态,下面是线程的状态转换图:
start()
。start()
后,线程处于可执行状态,等待操作系统调度执行。run()
方法。Java 中有三种常见的方式来创建线程:继承 Thread
类、实现 Runnable
接口和使用线程池 ExecutorService
。我们来对比一下这三种方式,看看它们的优缺点和适用场景。
方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
继承 Thread 类 |
简单易用,适用于任务较简单的情况 | 继承限制,不能再继承其他类 | 适用于单一任务的简单应用 |
实现 Runnable 接口 |
可以实现多个线程共享同一任务,灵活性高 | 不支持直接获取线程的返回值 | 适用于需要多个线程执行相同任务的场景 |
使用 ExecutorService |
高效管理线程池,适用于大量任务的并发执行 | 相对复杂,使用不当可能导致资源泄露 | 适用于高并发、大量任务的场景 |
Thread
类 继承 Thread
类并重写 run()
方法是最简单的方式。在这个方式中,每个线程都对应一个 Thread
类的实例。
示例:继承 Thread
类创建线程
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + " is running!");
}
}
public class ThreadExample {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.start(); // 启动线程
MyThread thread2 = new MyThread();
thread2.start(); // 启动线程
}
}
start()
方法用于启动线程,线程一旦启动就进入 可运行 状态。run()
方法是线程的执行体,线程启动后会执行此方法。Runnable
接口 ♂️相比继承 Thread
,实现 Runnable
接口可以让我们实现更灵活的多线程应用。多个线程可以共享同一个 Runnable
实例,尤其适合多个线程执行相同任务的场景。
示例:实现 Runnable
接口创建线程
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + " is running!");
}
}
public class RunnableExample {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
thread1.start(); // 启动线程
Thread thread2 = new Thread(myRunnable);
thread2.start(); // 启动线程
}
}
Runnable
接口,多个线程可以共享同一个 Runnable
实例,这在任务相同的场景下非常有用。run()
方法包含了线程要执行的代码。ExecutorService
线程池 ️当我们需要创建大量线程时,直接通过 Thread
类或 Runnable
接口来管理线程会显得低效和繁琐。ExecutorService
提供了一种更高效的线程管理方式,能够复用线程池中的线程,避免线程的频繁创建和销毁。
示例:使用 ExecutorService
创建线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceExample {
public static void main(String[] args) {
// 创建一个固定大小为 3 的线程池
ExecutorService executorService = Executors.newFixedThreadPool(3);
// 提交任务给线程池
for (int i = 0; i < 5; i++) {
executorService.submit(() -> {
System.out.println("Thread " + Thread.currentThread().getId() + " is executing task");
});
}
// 关闭线程池
executorService.shutdown();
}
}
ExecutorService
允许我们创建一个固定数量的线程,并复用它们来执行多个任务。submit()
方法将任务提交给线程池,线程池中的线程会并发执行这些任务。线程的优先级决定了线程在 CPU 中的调度顺序。Java 中的线程有 10 个优先级,数字越大,线程的优先级越高。默认情况下,线程的优先级为 5。
优先级设置可以影响多线程程序的性能,但我们通常不建议过度依赖它,因为操作系统的调度器会决定线程的实际执行顺序。
示例:设置线程优先级
class PriorityThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getId() + " has priority: " + getPriority());
}
}
public class ThreadPriorityExample {
public static void main(String[] args) {
Thread thread1 = new PriorityThread();
thread1.setPriority(Thread.MIN_PRIORITY); // 设置最低优先级
thread1.start();
Thread thread2 = new PriorityThread();
thread2.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级
thread2.start();
Thread thread3 = new PriorityThread();
thread3.setPriority(Thread.NORM_PRIORITY); // 默认优先级
thread3.start();
}
}
setPriority()
方法设置线程的优先级。Thread.MIN_PRIORITY
(1)、Thread.MAX_PRIORITY
(10)、Thread.NORM_PRIORITY
(5)来设置优先级。当多个线程同时访问共享数据时,可能会出现数据竞争问题,导致程序错误。为了解决这个问题,我们通常使用同步机制(synchronized
)来保证线程安全。
示例:使用 synchronized
保证线程安全
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
死锁是指两个或多个线程互相等待对方释放资源,导致程序永远无法继续执行。避免死锁的策略包括:
思维导图
通过今天的学习,你已经掌握了 Java 中线程的创建与运行方式,从继承 Thread
类到实现 Runnable
接口,再到使用线程池 ExecutorService
,每种方式都有其独特的优势和适用场景。理解并灵活运用这些方式,将大大提高你的并发编程能力!
Thread
类:适合简单的线程创建。Runnable
接口:适合多个线程共享任务。ExecutorService
:适用于高并发、大量任务的线程管理。在接下来的文章中,我们将继续探讨Java中的同步和锁以及其他重要特性,敬请期待!
如果你觉得这篇文章对你有所帮助,欢迎点赞、收藏、分享!