计算很大数组中List的和

本文介绍了一种使用多线程和并行计算优化数组求和的方法,通过将任务分解到多个线程中,提高了计算效率。详细阐述了如何利用并发编程技术,如CyclicBarrier和ConcurrentLinkedQueue,实现并行处理和结果聚合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原帖地址:
[url]http://www.iteye.com/topic/711162[/url]


package thread;

import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CyclicBarrier;

public class SegmentCount {
public static void main(String[] args) {
int[] arr = new int[10123];
Random ran = new Random();
int sum = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = ran.nextInt(10000);
sum += arr[i];
}
System.out.println("结果应该为:" + sum);

// 多线程进行数组拆分计算
int threadSize = 10;
int avg = arr.length / threadSize;// 平均任务数
int surplus = arr.length % threadSize;// 剩余任务数
threadSize = surplus > 0 ? (++threadSize) : threadSize;
final ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();// 结果队列
CyclicBarrier barrier = new CyclicBarrier(threadSize, new Runnable() {
public void run() {
System.out.println("统计:");
System.out.println(queue);
int sum = 0;
Iterator<Integer> it = queue.iterator();
while (it.hasNext()) {
sum += Integer.valueOf(it.next().toString());
}
System.out.println("sum:" + sum);
}
});

for (int i = 1; i <= threadSize; i++) {
int end = i * avg;
end = (end > arr.length) ? arr.length : end;
new Thread(new Segment(barrier, arr, (i - 1) * avg, end, queue))
.start();
}
}
}

class Segment implements Runnable {
CyclicBarrier barrier;
int[] arr;
int start;
int end;
ConcurrentLinkedQueue<Integer> queue;

public Segment(CyclicBarrier barrier, int[] arr, int start, int end,
ConcurrentLinkedQueue<Integer> queue) {
super();
this.barrier = barrier;
this.arr = arr;
this.start = start;
this.end = end;
this.queue = queue;
}

int sum = 0;

public void run() {
System.out.println(Thread.currentThread().getName() + ",start:" + start
+ ",end:" + end);
for (int i = start; i < end; i++) {
sum += arr[i];
}
queue.offer(sum);
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}




package thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class SegmentCount2 {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
int[] arr = new int[10123];
Random ran = new Random();
int sum = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = ran.nextInt(10000);
sum += arr[i];
}
System.out.println("结果应该为:" + sum);

// 多线程进行数组拆分计算

int threadSize = 10;
int avg = arr.length / threadSize;// 平均任务数
int surplus = arr.length % threadSize;// 剩余任务数
threadSize = surplus > 0 ? (++threadSize) : threadSize;

ExecutorService pool = Executors.newCachedThreadPool();
List<Segment2> tasks = new ArrayList<Segment2>();
for (int i = 1; i <= threadSize; i++) {
int end = i * avg;
end = (end > arr.length) ? arr.length : end;
tasks.add(new Segment2(arr, (i - 1) * avg, end));
}
// 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。
List<Future<Integer>> result = pool.invokeAll(tasks);

int summ = 0;
for (int i = 0; i < result.size(); i++) {
FutureTask<Integer> task = (FutureTask<Integer>) result.get(i);
summ += Integer.valueOf(task.get().toString());
}
System.out.println("总共:" + summ);
pool.shutdown();
}
}

class Segment2 implements Callable<Integer> {
int[] arr;
int start;
int end;

public Segment2(int[] arr, int start, int end) {
super();
this.arr = arr;
this.start = start;
this.end = end;
}

int sum = 0;

public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + ",start:" + start
+ ",end:" + end);
for (int i = start; i < end; i++) {
sum += arr[i];
}
return sum;
}
}




package thread;

import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;

public class SegmentCount3 {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
int[] arr = new int[10123];
Random ran = new Random();
int sum = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = ran.nextInt(10000);
sum += arr[i];
}
System.out.println("结果应该为:" + sum);

// 多线程进行数组拆分计算

int threadSize = 10;
int avg = arr.length / threadSize;// 平均任务数
int surplus = arr.length % threadSize;// 剩余任务数
threadSize = surplus > 0 ? (++threadSize) : threadSize;
final ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();// 结果队列
CountDownLatch beginSignal = new CountDownLatch(1);
CountDownLatch endSignal = new CountDownLatch(threadSize);

for (int i = 1; i <= threadSize; i++) {
int end = i * avg;
end = (end > arr.length) ? arr.length : end;
new Thread(new Segment3(beginSignal, endSignal, arr, (i - 1) * avg,
end, queue)).start();
}
System.out.println("开闸");
beginSignal.countDown();
endSignal.await();
System.out.println("统计:" + queue);
Iterator<Integer> it = queue.iterator();
int summ = 0;
while (it.hasNext()) {
summ += it.next();
}
System.out.println(summ);
}
}

class Segment3 implements Runnable {
CountDownLatch beginSignal;
CountDownLatch endSignal;
int[] arr;
int start;
int end;
ConcurrentLinkedQueue<Integer> queue;

public Segment3(CountDownLatch beginSignal, CountDownLatch endSignal,
int[] arr, int start, int end, ConcurrentLinkedQueue<Integer> queue) {
super();
this.beginSignal = beginSignal;
this.endSignal = endSignal;
this.arr = arr;
this.start = start;
this.end = end;
this.queue = queue;
}

int sum = 0;

public void run() {
try {
beginSignal.await();

System.out.println(Thread.currentThread().getName() + ",start:"
+ start + ",end:" + end);

for (int i = start; i < end; i++) {
sum += arr[i];
}
queue.offer(sum);
endSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

### 定义大数组的方法 在不同编程语言中定义大型数组的方式有所不同。以下是几种常见编程语言中创建大小为 \(10^{18}\) 的数组方法。 #### C/C++ 由于内存限制,在实际应用中直接声明如此巨大的数组通常是不可行的,因为这超出了大多数系统的物理内存容量。然而理论上可以通过动态分配尝试: ```cpp #include <vector> int main() { std::vector<long long> largeArray; try { largeArray.resize(static_cast<size_t>(pow(10, 18))); // 尝试调整向量大小到1e18 } catch (const std::bad_alloc& e) { // 处理内存不足的情况 } } ``` 此代码片段展示了如何使用 `std::vector` 动态分配一个极大的数组[^1]。需要注意的是,这种操作几乎不可能成功完成,除非是在拥有极其庞大虚拟地址空间的环境中运行。 #### Python Python 中可以轻松地表示这样的概念性对象,但由于同样的原因——即所需的实际存储远超过任何合理硬件配置所能提供——这样做实际上并不可能实现: ```python try: huge_list = [0] * int(1e18) except MemoryError as me: print("无法分配足够的内存") ``` 这段脚本试图初始化长度为 \(10^{18}\) 的列表[^2]。同样地,这里主要是为了说明目的而写;真实场景下会遇到严重的性能瓶颈甚至崩溃。 #### Java Java 虽然支持较大的数据结构,但对于如此规模的数据集来说也是不切实际的选择: ```java public class Main { public static void main(String[] args) throws Exception { try { Long[] massiveArray = new Long[(long)Math.pow(10, 18)]; } catch (OutOfMemoryError oome){ System.out.println("超出可用堆空间"); } } } ``` 上述例子显示了尝试创建一个极大尺寸的数组时可能会触发异常处理机制[^3]。 对于真正需要处理海量数据的应用场合,建议考虑分布式计算框架如 Apache Spark 或者专门设计用来管理大规模数据集的技术栈,而不是单纯依赖单机环境下的简单数组结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值