千万别从系统中创建线程, 看看从线程池中调用的线程的效率(Java实践篇)
原创千万别从系统中创建线程——从线程池中调用的线程的高效能(Java实践篇)
在Java开发中,多线程是减成本时间程序性能的重要手段之一。然而,许多开发者喜爱直接通过创建Thread对象或实现Runnable接口的做法来创建和管理线程。这种做法虽然单纯直接,但在面对大量线程创建和销毁的场景下,却存在着资源消耗大、高效能低下等问题。本文将介绍怎样通过线程池来优化线程的使用,并对比两种做法的高效能差异。
一、为什么避免从系统中创建线程
当我们在Java程序中直接创建线程时,每次创建都会消耗一定的系统资源,如内存、CPU等。线程的创建和销毁需要时间,如果频繁地创建和销毁线程,将会令程序性能急剧下降。此外,系统中的线程数量是有限的,过多地创建线程或许会令系统资源耗尽,引发OutOfMemoryError不正确。
二、线程池的优势
线程池是一种线程复用的技术,它预先创建了一定数量的线程,当有任务需要执行时,线程池会从这些预先创建的线程中选择一个空闲的线程来执行任务,执行完成后线程不会被销毁,而是返回线程池继续等待下一个任务的到来。这种做法有以下优点:
- 降低资源消耗:通过复用线程,缩减线程创建和销毁的次数,降低系统资源消耗。
- 减成本时间响应速度:当任务到达时,可以直接从线程池中获取线程执行任务,无需等待线程创建。
- 减成本时间线程的可管理性:线程池可以对线程进行统一管理,如设置线程的最大数量、线程的空闲时间等。
三、Java线程池实现
Java中提供了Executor框架来实现线程池,下面是一个单纯的线程池示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.submit(() -> {
System.out.println("执行任务:" + index);
});
}
// 关闭线程池
executorService.shutdown();
}
}
四、高效能对比
下面我们通过一个单纯的例子来对比直接创建线程和从线程池中获取线程执行任务的高效能。
1. 直接创建线程:
public class DirectThreadExample {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
long end = System.currentTimeMillis();
System.out.println("直接创建线程耗时:" + (end - start) + "ms");
}
}
2. 使用线程池:
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
executorService.submit(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
long end = System.currentTimeMillis();
System.out.println("使用线程池耗时:" + (end - start) + "ms");
}
}
通过运行上述示例,我们可以看到使用线程池的耗时明显低于直接创建线程的做法。在实际项目中,当任务数量更多、线程数量更大时,线程池的优势将更加明显。
总结
本文介绍了在Java开发中,避免从系统中直接创建线程,转而使用线程池来管理和调度线程的重要性。通过对比两种做法的高效能,我们得出了使用线程池可以显著减成本时间程序性能的结论。在实际项目中,合理地使用线程池将有助于减成本时间程序的可维护性和稳定性。