线程池的使用
线程池使用方法整理
ALL IN ONE
package multiThread.ThreadPool;
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) {
// 使用线程池的方式有两种
// 一般不使用Executors 创建线程池,因为其内部使用的是无界的阻塞队列,容易造成OOM
// 方式1 通过Executors工具类创建线程池
// 1.1 创建固定大小的线程池
ExecutorService service = Executors.newFixedThreadPool(3);
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("固定大小线程池执行任务 "+Thread.currentThread().getName());
}
});
// 1.2 创建单线程的线程池
ExecutorService service1 = Executors.newSingleThreadExecutor();
service1.execute(new Runnable() {
@Override
public void run() {
System.out.println("单线程线程池执行任务 "+Thread.currentThread().getName());
}
});
// 1.3 创建可缓存的线程池
ExecutorService service2 = Executors.newCachedThreadPool();
service2.execute(new Runnable() {
@Override
public void run() {
System.out.println("可缓存线程池执行任务 "+Thread.currentThread().getName());
}
});
// 1.4 创建可调度的线程池
ScheduledExecutorService service3 = Executors.newScheduledThreadPool(2);
Runnable task = () -> {
System.out.println("Task executed at: " + System.currentTimeMillis());
};
// 以固定的时间间隔(2 秒)执行任务
service3.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);
// 等待一段时间,然后关闭线程池
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
service3.shutdown();
// 方式2 通过ThreadPoolExecutor创建线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
5,
1,
TimeUnit.SECONDS,
new java.util.concurrent.ArrayBlockingQueue<>(10)
);
for (int i = 0; i < 10; i++) {
// 通过execute方法提交任务
int finalI = i;
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程池执行任务 "+ finalI +" "+Thread.currentThread().getName());
}
});
}
}
}
如何使用ThreadPoolExecutor
ThreadPoolExecutor
是 Java 中用于创建和管理线程池的类,它提供了灵活的线程管理和任务调度机制。下面是一个简单的例子,演示如何使用 ThreadPoolExecutor
:
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建一个 ThreadPoolExecutor
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
5, // 最大线程数
1, // 线程空闲时间
TimeUnit.SECONDS, // 空闲时间单位
new java.util.concurrent.ArrayBlockingQueue<>(10) // 阻塞队列
);
// 提交任务给线程池
for (int i = 0; i < 20; i++) {
int finalI = i;
executor.submit(() -> {
System.out.println("Task " + finalI + " is running in thread " + Thread.currentThread().getName());
});
}
// 关闭线程池
executor.shutdown();
}
}
在这个例子中,我们创建了一个 ThreadPoolExecutor
实例,并设置了核心线程数、最大线程数、线程空闲时间和阻塞队列等参数。然后,我们通过 executor.submit()
方法提交了一些任务给线程池执行。最后,通过 executor.shutdown()
方法关闭线程池。
ThreadPoolExecutor
还有其他很多配置选项和方法,可以根据需求进行调整,例如设置拒绝策略、预启动核心线程、设置线程工厂等。请根据具体的应用场景来选择适当的参数和方法。
ThreadPoolExecutor 的submit 和 execute 方法区别
ThreadPoolExecutor
类提供了 submit()
方法和 execute()
方法,用于提交任务给线程池执行。它们在功能上有些许区别:
submit()
方法
submit()
方法可以接受Runnable
或Callable
任务,并返回一个Future
对象,通过Future
对象可以获取任务的执行结果或取消任务。submit()
方法的返回值是Future
类型,可以通过调用Future.get()
方法来获取任务的执行结果,或者使用Future.cancel()
方法来取消任务。submit()
方法还可以接受一个泛型参数,用于指定任务返回的结果类型。
Future<?> future = executor.submit(() -> {
// 任务逻辑
});
execute()
方法:
execute()
方法只能接受Runnable
任务,它没有返回值,因此无法获取任务的执行结果。execute()
方法更适用于只关心任务的执行而不关心结果的情况。
executor.execute(() -> {
// 任务逻辑
});
在大多数情况下,如果你关心任务的执行结果,需要等待任务完成并获取结果,就应该使用 submit()
方法。如果你只需要提交一个简单的任务给线程池执行,而不需要获取任务的执行结果,可以使用 execute()
方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix