使用multithreading处理对java数组进行分区和分析

我必须通过for循环初始化一个浮点[12000] 12000次。 然后我扫描数组以查找超过特定阈值的值。 如果值超过阈值,我操纵某个对象的实例变量。

例:

Random random = new Random(); float[] x = new float[12000]; for (int i = 0; i < x.length; i++) { x[i] = random.nextFloat(); } for (int i = 0; i = 0.75) { \\ do something interesting } } 

基本上,我必须更改数组的值,并在每次长度为12000时在新数组上执行12000次。“有趣的”代码只是在另一个数据结构中查找该索引并调用setter。 根据我的系统时间计算,我需要大约13个小时。 我的机器上有8个处理器。

我如何利用java的multithreadingfunction? 我特意寻找分区初始化和扫描数组的线程解决方案。 使用线程的源代码将不胜感激。

你可以把它分成8个不同的线程做这样的事情

 public class Worker implements Runnable { final private int minIndex; // first index, inclusive final private int maxIndex; // last index, exclusive final private float[] data; public Worker(int minIndex, int maxIndex, float[] data) { this.minIndex = minIndex; this.maxIndex = maxIndex; this.data = data; } public void run() { for(int i = minIndex; i < maxIndex; i++) { if(data[i] >= 0.75) { // do something interesting } } } } // *** Main Thread *** float[] data = new float[12000]; int increment = data.length / 8; for(int i = 0; i < 8; i++) { new Thread(new Worker(i * increment, (i + 1) * increment, data)).start(); } 

这将数组分为8个不同的线程。 或者,另一种选择是:

 public class Worker implements Runnable { final private BlockingQueue queue; final private float[] data; public Worker(BlockingQueue queue) { this.queue = queue; this.data = data; } public void run() { while(true) { int i = queue.take(); float f = data[i]; // do something interesting to f } } } // *** Main Thread *** BlockingQueue queue = new LinkedBlockingQueue<>(); float[] data = new float[12000]; for(int i = 0; i < 8; i++) { new Thread(new Worker(queue, data)).start(); } for(int i = 0; i < data.length; i++) { if (data[i] >= 0.75) { queue.offer(i); } } 

这使用一个线程迭代数组并找到有趣的数字,然后使用八个工作线程对有趣的数字做一些有趣的事情。 我倾向于选择这种方法,因为第一种方法可能会导致一个工作线程必须处理一千个有趣的数字,而另一个工作线程只需要处理一些有趣的数字; 这种方法确保每个线程需要处理大约相同数量的有趣数字。

我省略了很多东西,比如如何使用Executors以及如何关闭你的工作线程等等 - 这是一个关于它的教程 。

编辑要获取代码并在8个线程上运行12000次,您将执行以下操作:

 public class Worker implements Runnable { private final int numberOfIterations; private final float[] x = new float[12000]; public Worker(int numberOfIterations) { this.numberOfIterations = numberOfIterations; } public void run() { for(int i = 0; i < numberOfIterations; i++) { Random random = new Random(); for (int i = 0; i < x.length; i++) { x[i] = random.nextFloat(); } for (int i = 0; i < x.length; i++) { if (x[i] >= 0.75) { \\ do something interesting } } } } } // *** Main Thread *** Thread[] threads = new Thread[8]; for(int i = 0; i < 8; i++) { threads[i] = new Thread(new Worker(12000/8)); threads[i].start(); } for(int i = 0; i < 8; i++) { threads[i].join(); } 

八个线程中的每一个将运行1500次迭代的“初始化浮点数组,迭代浮点数组”代码。 然后, join方法将等待线程完成。 确保// do something interesting的代码是线程安全的 - 你说你正在调用一个setter,所以要确保多个线程不会调用相同的setter,否则setter会被同步,或者否则你在setter中使用像AtomicInteger这样的东西。 如果你有任何疑问,请发布setter代码。