java线程池list_java定义⼀个线程池循环遍历list,进⾏读写操
作
展开全部
import java.util.List;
import urrent.Callable;
import urrent.ExecutionException;
import urrent.ExecutorService;
import urrent.Executors;
import urrent.Future;
/**
* 并发处理器
* 适⽤于如下场景(举例):
* ⼀个任务队列, 有150个任务需要62616964757a686964616fe58685e5aeb931333361303565并发处理,使⽤此对象,可以每次并发执⾏20次(可设置),则总共串⾏执⾏8次并发,可获取执⾏结果
*
* @param 类型T限制为任务Callable使⽤的数据对象和返回结果的数据对象为同⼀个bean
*/
public class ConcurrentExcutor
{
/** ⾮空,所有任务数组 */
private Callable[] tasks;
/** ⾮空,每次并发需要处理的任务数 */
private int numb;
/** 可选,存放返回结果,这⾥有个限制,泛型T必须为Callable返回的类型T */
private List result;
/**
* ⽆参构造
*/
public ConcurrentExcutor()
{
super();
}
/**
* 不需要返回结果的任务⽤此创建对象
* @param tasks
* @param numb
*/
public ConcurrentExcutor(Callable[] tasks, int numb)
{
super();
this.tasks = tasks;
this.numb = numb;
}
/**
* 需要结果集⽤此⽅法创建对象
* @param tasks
* @param numb
* @param result
*/
public ConcurrentExcutor(Callable[] tasks, int numb, List result) {
super();
this.tasks = tasks;
this.numb = numb;
}
public void excute()
{
// 参数校验
if(tasks == null || numb
{
return;
}
// 待处理的任务数
int num = tasks.length;
if(num == 0)
{
return;
}
// 第⼀层循环,每numb条数据作为⼀次并发
for(int i=0; i
{
// ⽤于记录此次numb条任务的处理结果
Future[] futureArray;
if(numb > num)
{
futureArray = new Future[num];
}
else
{
futureArray = new Future[numb];
}
// 创建线程容器
ExecutorService es = wCachedThreadPool(); // 第⼆层循环,针对这numb条数据进⾏处理
for(int j=i*numb; j
{
// 如果超出数组长度,退出循环
if(j + 1 > num)
{
break;
}
// 执⾏任务,并设置Future到数组中
futureArray[j%numb] = es.submit(tasks[j]);
}
// 将结果放⼊result中
if (result != null)
{
for (int j = 0; j
{
try
{
if(futureArray[j] != null)
{
Object o = futureArray[j].get();
result.add((T)o);
}
}
catch (InterruptedException e)
{
System.out.println("处理Future时发⽣InterruptedException异常,⽬标Future为: " + futureArray[j].toString());
e.printStackTrace();
}
catch (ExecutionException e)
{
System.out.println("处理Future时发⽣ExecutionException异常,⽬标Future为: " + futureArray[j].toString());
e.printStackTrace();
}
}
}
es.shutdown();
}
}
追问
for (int i = 0; i < list.size(); i++) {
new Thread( "" + i) {
String id = Id();
public void run() {
test part =info(id);
}
}.start();
}
我以前是直接遍历⼀次就建⼀个线程,你给的这个我也不知道怎么去调⽤,
追答
你这样直接循环list不太好,如果list有1000条数据,你瞬间就起了⼀千个线程,⽽且需要⼈为写代码注
意同步问题。你这个代码最严重的问题是,⼦线程处理结果你主线程要拿到很⿇烦,这⼀点在真正项⽬应⽤中很重要!
我发给你的那段代码我测过可以⽤的,⼤概调⽤思路就是:把你“遍历⼀次需要15秒左右”这个事情写到⼀个类⾥⾯,类实现Callable接⼝,
这个我们称之为⼀个任务
然后你不是有个List吗,遍历这个list,构建⼀个任务数组
创建ConcurrentExcutor对象并执⾏数组⾥⾯的任务
下⾯是我⾃⼰项⽬中的调⽤代码,供你参考(ProcessNumTask就是那个实现Callable的任务):
ProcessNumTask[] tasks = new ProcessNumTask[tempList.size()];
for(int i=0; i
{
tasks[i] = new (i));
}
ConcurrentExcutor ce = new ConcurrentExcutor(tasks, 5, result);
已赞过
已踩过<
你对这个回答的评价是?
评论
java线程池创建的四种收起
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论