如何充分利用多核CPU,计算list中元素的和?

xiemk2005 2009-06-28 10:31:17
有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果。
...全文
196 10 打赏 收藏 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiemk2005 2009-06-29
  • 打赏
  • 举报
回复
用线程做这点应该没什么疑问。
现在问题是1)如何设计,使得每个线程安全的取出list的元素,即不会重复取出某个元素;
2)怎样把各个线程的求和得到的值合并起来
也就是考虑使用哪个对象作为同步的对象锁?
2楼的思路应该可行。
[Quote=引用 2 楼 mianfeidog 的回复:]
我会把list分段,各段由线程计算元素和。
[/Quote]
Inhibitory 2009-06-29
  • 打赏
  • 举报
回复
可以使用Callable<Integer>和Future, FutureTask,这种多线程模式来进行计算,构建计算线程队列。然后再使用一个专门的线程来监视所有的计算线程,当每个线程计算完成后,取得结果计算结果,并且把此线程从计算线程队列中移除。

class Computer implements Callable<Integer> {
private List<Integer> list;
public Computer(List<Integer> list) {
this.list = list;
}

public Integer call() {
int sum = 0;
for (Integer value : list) {
sum += value.intValue();
}

return sum;
}
}


// 数据list分段
List<Future<Integer>> futureList = new LinkdedList<Future<Integer>>();
...分段
Computer computer = new Computer(listSegment);
FutureTask<Integer> task = new FutureTask(computer);
futureList.add(task);
Thread thread = new Thread(task);
thread.start(); // 开始进行计算.


// 监视计算任务的线程
class ComputationMonitor extends new Thread() {
private int sum;

public void run() {
while (!futureList.isEmpty()) {
for (Future<Integer> task : futureList) {
if (task.isDone()) {
sum += task.get().intValue();
futureList.remove(task); // 注意这里的细节,这个futureList是可以修改的,所以要去自己改一下,这里只是描述算法的过程。
}
}
}

// 到此,计算完成,完成后要怎么处理,可以加入代码..............
}
}
longq121 2009-06-29
  • 打赏
  • 举报
回复
用线程做吧,
Yedy2000 2009-06-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 preferme 的回复:]
Java codepackage houlei.util.concurrent;

import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* 用于多线程求纯整数List之和的类。未进行异常处理。
* <p>
* 该类创建于 2009-6-29 上午10:04:49
* @versi…
[/Quote]

用 List<Integer> list = new LinkedList<Integer>();再结合线程不见得会提高速度,因为你线程用了listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。由于LinkedList这个链表要找到指定位置位置的元素,也就是listIterator(int index)的开始是需要遍历的。

用arraylist也许还能提高性能。
冰思雨 2009-06-29
  • 打赏
  • 举报
回复
package houlei.util.concurrent;

import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* 用于多线程求纯整数List之和的类。未进行异常处理。
* <p>
* 该类创建于 2009-6-29 上午10:04:49
* @version 1.0.0
* @author 侯磊
*/
public class SumCounter {
private List<Integer> list ;
private int totalThreads ;
private CyclicBarrier barrier ;
private long sum;

public SumCounter(List<Integer> list, int totalThreads) {
super();
this.list = list;
this.totalThreads = totalThreads;
barrier = new CyclicBarrier(totalThreads+1);
}

public long doSum(){
ExecutorService exec = Executors.newFixedThreadPool(totalThreads);
for(int i=0;i<totalThreads;i++){
int len = list.size()/totalThreads;
exec.submit(new SumSubTask(list, i*len, i*len>=list.size()?list.size():len));
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
exec.shutdown();
return sum;
}

class SumSubTask implements Runnable{
private List<Integer> list ;
private int offset;
private int len;
public SumSubTask(List<Integer> list, int offset, int len) {
super();
this.list = list;
this.offset = offset;
this.len = len;
}

public void run() {
long subSum = 0L;
ListIterator<Integer> itr = list.listIterator(offset);
for(int i=0;itr.hasNext()&&i<len;i++){
subSum +=itr.next();
}
synchronized (SumCounter.this) {
sum+=subSum;
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("线程:"+Thread.currentThread().getName()+"\tSubSum:"+subSum);
}

}
}

package houlei.util.concurrent;

import java.util.LinkedList;
import java.util.List;

/**
* 用于多线程求纯整数List之和的测试代码入口。
* <p>
* 该类创建于 2009-6-29 上午10:03:52
* @version 1.0.0
* @author 侯磊
*/
public class Main {

public static void main(String[] args) {
List<Integer> list = getTheList();
int totalThreads = 5;
SumCounter sc = new SumCounter(list,totalThreads);
long sum = sc.doSum();
System.out.println(sum);
}

private static List<Integer> getTheList() {
List<Integer> list = new LinkedList<Integer>();
for(int i=1;i<=10000;i++){
list.add(i);
}
return list;
}

}
oklinsong 2009-06-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mianfeidog 的回复:]
我会把list分段,各段由线程计算元素和。
[/Quote]
顶!
thinkhejie 2009-06-29
  • 打赏
  • 举报
回复
线程的同步?
Inhibitory 2009-06-29
  • 打赏
  • 举报
回复
// 监视计算任务的线程
这个同样可以使用ExecutorService来完成,不需要自己去实现,可以参考下面的示例:
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class InvokeAllAndAnyTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newCachedThreadPool();
List<Callable<Integer>> tasks = new LinkedList<Callable<Integer>>();
for (int i = 0; i < 8; ++i) {
tasks.add(new Printer(i));
}
List<Future<Integer>> futures = pool.invokeAll(tasks); // 多线程进行计算,但当前线程会阻塞在这里,当所有计算完成后,返回结果。

System.out.println("...............................................");
for (Future<Integer> future : futures) {
System.out.println(future.get());
}

pool.shutdown();
}
}

class Printer implements Callable<Integer> {
private int id;
private static final int DELAY = 1000;

public Printer(int id) {
this.id = id;
}

public Integer call() {
try {
int times = 10;
for (int i = 0; i < times; ++i) {
System.out.println("Id:" + id + " times:" + i);

Thread.sleep((int) (DELAY * Math.random()));
}
} catch (InterruptedException e) {
}

return id;
}
}
mianfeidog 2009-06-28
  • 打赏
  • 举报
回复
我会把list分段,各段由线程计算元素和。
bigbug9002 2009-06-28
  • 打赏
  • 举报
回复
多线程吧
大气污染是影响公众健康与生态环境的重要问题,精准的空气质量时空预测与污染源贡献度量化是精准治污的关键支撑。针对现有研究多源融合不充分、时空关联刻画不足、预测与源解析割裂三方面缺陷,本文设计实现了城市空气质量时空预测与污染源贡献度分析系统,融合监测、气象、工业排放与交通四类数据,构建基于时空注意力的LSTM(STAM-LSTM)预测模型与基于正定矩阵因子分解(PMF)的源解析模型,形成数据融合-特征工程-预测-源解析-可视化闭环。 系统实现四类数据时空对齐与融合,构建时序与空间邻域特征,以普通克里金插值生成1km网格浓度场;STAM-LSTM引入时空注意力自适应学习站点间污染传输时变权重,以72小时输入预测未来24小时逐小时PM2.5浓度;PMF识别交通、工业、燃煤、扬尘与二次生成五个源因子,量化各源全年贡献度并分析时空演变。 实验表明:STAM-LSTM预测RMSE 24.6、MAE 17.8、R² 0.88,相对LSTM基线(30.2)提升18.5%;普通克里金插值误差8.9,优于反距离加权(11.4);源解析显示交通源28.4%、工业源23.1%、燃煤源19.6%为主要贡献源,冬季燃煤源升至27.3%、早高峰交通源达34.8%,下风向工业源贡献高出上风向8~12个百分点;减排情景显示交通源减排20%可使年均PM2.5下降5.7%,与源贡献度排序一致。 系统按五模块14组件实现,功能测试16项用例全部通过,为大气污染预警、源管控与减排政策制定提供了决策依据。 【课程报告内容】 摘要 第1章 绪论 第2章 相关技术与理论 第3章 系统需求分析 第4章 系统总体设计 第5章 系统详细设计与实现 第6章 系统测试与分析 第7章 总结与展望 参考文献 附件-实现指南

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧