【问题标题】:Dividing an ArrayList and passing it to different threads in Java划分一个 ArrayList 并将其传递给 Java 中的不同线程
【发布时间】:2017-05-19 17:20:19
【问题描述】:

我正在尝试将 ArrayList 划分为多个线程,以便它们稍后可以执行 RMI 调用。但是,即使在任何 RMI 开始之前,我也无法将 subList 作为参数传递。以下程序的输出是:

get(1): 28.833612828660367
get(1): 28.833612828660367

而我希望这些数字会有所不同。这意味着每个线程都接收完全相同的数组。我不太了解Java,所以可能是什么问题?

在下面的代码中,N 是数组中的总元素数,K 是程序应该启动的线程数。

package rmi;

import java.rmi.Naming;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class Client {

    private static final int N = 10;
    private static final int K = 2;    

    public static void main(String[] args) {

        ArrayList<Double> vector = new ArrayList<>();

        for (int j=0; j<N; j++){
            vector.add(ThreadLocalRandom.current().nextDouble(1, 100));
        }

        for (int i=0; i<K; i++){
            new ClientThread(vector.subList(i*N/K, i*N/K+N/K-1)).start();
        }
    }

}


class ClientThread extends Thread{

    private static List<Double> vector;

    public ClientThread(List<Double> vectorArg){
        vector = vectorArg;
    }

    @Override
    public void run(){
        try {
            Service s = (Service) Naming.lookup("rmi://localhost:1099/Servico");
            System.out.println("get(1): "+vector.get(1));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

谢谢!

【问题讨论】:

  • 我不确定我是否理解这种安排的目的。您可以使用线程安全集合而不是拆分列表,然后每个线程都可以从中获取数据吗?
  • 我尝试制作一个 ArrayList> (我能想到的最好的东西 - 列表列表),并将每个独立数组传递给每个线程。结果是一样的。是否可能与生成随机数的方式有关?
  • 程序背后的想法是允许通过每个线程内的 RMI 调用并行处理数组,从而加快处理速度。那部分是从上面的代码中抽象出来的。
  • 您可以使用线程之间共享的并发队列来实现相同的目的。子列表分区目前看起来不太正确。
  • 你说得对,我认为这会奏效。但是,我可能不得不担心同步对队列的访问,对吗?我可能会尝试,但很想了解为什么上面的代码不起作用。

标签: java multithreading arraylist


【解决方案1】:

只需从 ClientThread 类的字段 vector 中删除静态

class ClientThread extends Thread {

    private List<Double> vector;

    public ClientThread(List<Double> vectorArg) {
        vector = vectorArg;
    }

    @Override
    public void run() {
        try {
            Service s = (Service) Naming.lookup("rmi://localhost:1099/Servico");
            System.out.println("get(1): " + vector.get(1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2019-05-27
    • 2018-03-19
    • 2020-09-22
    • 2021-05-06
    • 2015-09-27
    • 2013-12-10
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多