线程池原理
线程池是多线程处理中的一种实现模式。程序员可以直接利用线程池,而不需要手动管理线程的生命周期。线程池不仅可以提高程序的性能,减小线程的创建和销毁时间,而且可以有效地管理和控制线程的最大并发数。
线程池的好处包括:
资源利用: 线程池可以更有效地利用系统资源,当线程完成任务后,它将被重新用于执行新的任务,而不是被销毁。
线程管理: 线程池可以帮助你管理线程的生命周期,避免手动创建和销毁线程带来的问题。
性能提升: 线程的创建和销毁都需要时间和系统资源,而使用线程池可以避免这种开销,提升应用程序的性能。
__并发控制:__线程池可以控制并发线程的数量,防止系统资源的过度使用。
__任务调度:__程池提供了更灵活的任务调度机制,你可以根据需要安排任务的执行顺序。
响应更快: 线程池中的线程在需要时可以立即开始执行,不需要等待线程的创建。
程序更简单: 使用线程池,你不需要处理线程的创建、销毁和管理,可以让你的程序更简洁。
示例代码
在Java中,可以通过java.util.concurrent包中的ExecutorService接口和Executors类来实现线程池。以下是一个简单的例子:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 为线程池内的线程分配任务
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker); // 在线程池中执行线程
}
// 关闭线程池,此时线程池不再接受新的任务,但会继续处理已提交的任务
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("所有线程运行结束");
}
}
class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 开始执行命令 : " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " 完成执行命令 : " + command);
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在这个例子中,我们首先创建了一个固定大小的线程池,大小为5。然后创建了10个任务(WorkerThread),并将它们提交给线程池执行。每个任务就是一个线程,它会在执行完自己的任务后自动结束。当所有的任务都执行完毕后,我们调用executor.shutdown()来关闭线程池。这个过程是异步的,也就是说,当你调用shutdown()方法时,线程池可能还在处理已提交的任务。因此,我们用一个循环来等待所有的任务都执行完毕。
/**
* 自定义线程池
* cofig配置
*/
@Configuration
public class ThreadPoolExecutorConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor() {
ThreadFactory threadFactory = new ThreadFactory() {
private int count = 1;
@Override
public Thread newThread(@NotNull Runnable r) {
Thread thread = new Thread(r);
thread.setName("线程" + count);
count++;
return thread;
}
};
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor
(2, 4, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000), threadFactory);
return threadPoolExecutor;
}
boolean c = chartService.updateById(updateChartResult);
if (!c) {
handleChartUpdateError(chart.getId(), "更新图表成功状态失败");
}
},threadPoolExecutor);
CompletableFuture.runAsync(() -> {}, threadPoolExecutor);
这段代码是Java中的一个示例,它使用了CompletableFuture
和ThreadPoolExecutor
。CompletableFuture
是Java 8引入的一种新的Future,它是对传统Future的增强,提供了非常强大的Future的组合式异步编程能力。ThreadPoolExecutor
则是Java中的一个线程池实现,可以让我们更好地管理和控制线程。
这段代码的意思是:创建一个新的CompletableFuture
,然后在这个CompletableFuture
中异步地运行一个空的lambda表达式(也就是什么都不做)。这个lambda表达式将在你提供的ThreadPoolExecutor
线程池中运行。
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
CompletableFuture.runAsync(() -> {
// 你的代码
}, threadPoolExecutor);
# 在这个例子中,我们首先创建了一个包含10个线程的线程池。然后,我们使用`CompletableFuture.runAsync`来在这个线程池中异步地运行一个lambda表达式。这个lambda表达式在这里为空,但是你可以在其中放入你想要异步执行的代码。
引言:线程池是不是更适用于需要多个线程处理任务而MQ更适用于服务间通信与应用解耦