线程池是一种管理线程的机制,可以重复利用已经创建的线程,避免频繁地创建和销毁线程的开销。可以使用Executors类的静态方法创建不同类型的线程池,然后将Runnable或Callable对象提交给线程池执行。
下面简单介绍一个 实战中应用的实例
int perCount = 50;
int size = listGoodSourceDTO.size();
int mol = size % perCount;
int loop = (int) Math.ceil(size / (double) perCount);
逐步解释:
-
perCount: 这个变量代表每个循环中处理的元素数量,设定为50。
-
mol: 这个变量用来计算列表大小除以每个循环处理的数量的余数。通过
size % perCount
计算得到。它的作用是确定最后一个循环中需要处理的元素个数,因为最后一个循环可能不足perCount
个元素。 -
loop: 这个变量计算了总共需要进行的循环次数。使用了
Math.ceil()
方法来确保即使是小数除法,结果也向上取整为整数。具体计算为(int) Math.ceil(size / (double) perCount)
。这个表达式将列表的大小除以每个循环处理的元素数量,得到循环的总次数。
//合理的创建线程中的执行线程数
ExecutorService pool = Executors.newFixedThreadPool(loop);
List<Future> list = new ArrayList<>();
for (int i = 0; i < loop; i++) {
List<BizGoodsOfSourceDTO> listUnit;
if (i == loop - 1 && mol != 0) {
listUnit = listGoodSourceDTO.subList(i * perCount, size);
} else {
listUnit = listGoodSourceDTO.subList(i * perCount, (i + 1) * perCount);
}
Callable callable = new InsertGsInfosCallable(listUnit);
Future submit = pool.submit(callable);
list.add(submit);
}
//关闭线程池
pool.shutdown();
ExecutorService pool = Executors.newFixedThreadPool(loop);
这行代码创建了一个固定大小的线程池 (
ExecutorService
),其大小由变量loop
指定。loop由上边计算得出,如果
loop
的值为 5,那么线程池中将会有 5 个线程可供使用。
-
InsertGsInfosCallable: 这是一个实现了
Callable
接口的类,用来表示一个可调用的任务。它的构造函数InsertGsInfosCallable(listUnit)
可能接受一个参数listUnit
,用于初始化任务所需的数据或状态。 -
callable: 这是一个
Callable
对象的实例,即InsertGsInfosCallable
类的一个实例。通过new InsertGsInfosCallable(listUnit)
创建了这个对象。 -
submit: 通过调用线程池的
submit()
方法,将callable
对象提交给线程池进行执行。submit(callable)
返回一个Future
对象,表示异步计算的结果。在这里,Future submit
可能是一个Future
类型的引用,用来跟踪任务的执行状态和获取任务的结果。 -
boolean res = true; StringBuffer stringBuffer = new StringBuffer(); for (Future future : list) { Response<Boolean> response = (Response<Boolean>) future.get(); boolean success = response.isSuccess(); res = res && success; if (!success) { stringBuffer.append(response.getData()); } }
-
future.get(): 在循环中,通过
future.get()
方法获取每个异步任务的执行结果。Future
类型的对象可以通过get()
方法来获取其关联任务的结果。在这里,假设每个Future
对象的结果类型是Response<Boolean>
。 -
stringBuffer.append(response.getData()): 如果某个任务执行失败(即
success
为false
),则将该任务的数据信息(假设通过response.getData()
获取)追加到stringBuffer
中。stringBuffer
可能是一个StringBuffer
或StringBuilder
对象,用来收集所有失败任务的信息。
将上边代码块合并组合就是实战中的简单应用
-
使用固定大小的线程池适合于需要控制并发线程数量的场景,可以有效地限制同时执行的线程数量,避免资源耗尽或者系统过载的问题。