使用多线程处理对java数组进行分区和分析

使用多线程处理对java数组进行分区和分析,java,arrays,multithreading,Java,Arrays,Multithreading,我必须通过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 < x.length; i++) {

我必须通过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 < x.length; i++) {
  if (x[i] >= 0.75) {
  \\ do something interesting
  }
}
Random Random=new Random();
浮动[]x=新浮动[12000];
对于(int i=0;i=0.75){
\\做些有趣的事
}
}
基本上,我必须更改数组的值,并在一个新数组上执行12000次,每次长度为12000。“有趣的东西”代码只是在另一个数据结构中查找索引并调用setter。根据我的系统时间计算,大概需要13个小时。我的机器上有8个处理器


如何利用java的多线程功能?我特别寻找的线程解决方案,分区初始化和扫描阵列。使用线程的源代码将不胜感激。

您可以将其划分为八个不同的线程来执行类似的操作

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();
}
公共类工作程序实现可运行{
final private int minIndex;//第一个索引,包括
final private int maxIndex;//最后一个索引,独占
最终私有浮动[]数据;
公共工作者(int minIndex、int maxIndex、float[]数据){
this.minIndex=minIndex;
this.maxIndex=maxIndex;
这个数据=数据;
}
公开募捐{
对于(int i=minIndex;i=0.75){
//做些有趣的事
}
}
}
}
//***主线程***
浮动[]数据=新浮动[12000];
int增量=data.length/8;
对于(int i=0;i<8;i++){
新线程(新辅助线程(i*增量,(i+1)*增量,数据)).start();
}
这将在8个不同的线程之间划分数组。或者,另一种选择是:

public class Worker implements Runnable {
    final private BlockingQueue<Integer> queue;
    final private float[] data;

    public Worker(BlockingQueue<Integer> 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<Integer> 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);
    }
}
公共类工作程序实现可运行{
最终私有阻塞队列;
最终私有浮动[]数据;
公共工作者(封锁队列){
this.queue=队列;
这个数据=数据;
}
公开募捐{
while(true){
int i=queue.take();
浮动f=数据[i];
//做些有趣的事给f
}
}
}
//***主线程***
BlockingQueue=新建LinkedBlockingQueue();
浮动[]数据=新浮动[12000];
对于(int i=0;i<8;i++){
新线程(新工作线程(队列、数据)).start();
}
对于(int i=0;i=0.75){
(一)要约;
}
}
它使用一个线程遍历数组并找到感兴趣的数字,然后使用八个工作线程对感兴趣的数字执行一些有趣的操作。我倾向于使用这种方法,因为在第一种方法中,一个工作线程可能需要处理一千个有趣的数字,而另一个工作线程只需要处理几个有趣的数字;这种方法确保每个线程需要处理大约相同数量的感兴趣的数字

我省略了很多东西,比如如何使用和关闭你的工作线程等等

编辑要获取代码并在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();
}
公共类工作程序实现可运行{
私有最终整数迭代;
私人最终浮动[]x=新浮动[12000];
公共工作者(整数){
this.numberOfIterations=numberOfIterations;
}
公开募捐{
对于(int i=0;i=0.75){
\\做些有趣的事
}
}
}
}
}
//***主线程***
线程[]线程=新线程[8];
对于(int i=0;i<8;i++){
线程[i]=新线程(新工作线程(12000/8));
线程[i].start();
}
对于(int i=0;i<8;i++){
线程[i].join();
}

八个线程中的每一个都将运行1500次“初始化浮点数组,遍历浮点数组”代码的迭代。然后,
join
方法将等待线程完成。确保
//do something
中的代码是线程安全的-您说过您正在调用一个setter,所以请确保多个线程不会调用同一个setter,或者setter是同步的,或者在setter中使用类似于
原子整数的东西。如果您对此有任何疑问,请发布setter代码。

您对Java中的线程没有任何经验吗?您是否使用过Runnable或对Thread类执行过任何操作?对你在这里开始的知识感到好奇。13小时?这个有趣的方法一定很有趣。你所说的“每次在一个新数组上执行12000次”是什么意思。12000的迭代次数。我也很好奇@veritas问了些什么。你是否担心花在迭代上的时间或者花在做一些有趣的事情上的时间?答案可能会根据“做一些有趣的事情”的性质有很大的不同。每个线程是否可以为数组的一个子集“做一些有趣的事情”,而不必担心其他线程或数组的其他部分,或数组中其部分的变化?在第二种方法中,工作人员无法访问每个浮点的原始索引--这可能是许多应用程序中所必需的信息。@Keith Good point,我已经编辑了我的答案accordingly@Zim-谢谢你。我怀疑这会很有效。然而,更昂贵的计算是初始化