线程池的使用
线程池使用方法整理
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() 方法。

浙公网安备 33010602011771号