加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 04:12:00 所属栏目:Java 来源:网络整理
导读:我必须通过for循环初始化一个浮点[12000] 12000次.然后我扫描数组以查找超过特定阈值的值.如果值超过阈值,我操纵某个对象的实例变量. 例: Random random = new Random();float[] x = new float[12000];for (int i = 0; i x.length; i++) { x[i] = random.ne
我必须通过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
  }
}

基本上,我必须更改数组的值,并在每次长度为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();
}

这将数组分为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);
    }
}

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

我省略了很多东西,比如如何使用Executors以及如何关闭你的工作线程等 – here’s a tutorial on that.

编辑要获取代码并在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方法将等待线程完成.确保//做一些有趣的代码是线程安全的 – 你说你正在调用一个setter,所以要确保多个线程不会调用相同的setter,否则setter会被同步,或者否则你在setter中使用像AtomicInteger这样的东西.如果你对它有任何疑问,请发布setter代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读