简体   繁体   English

Java JSONArray和迭代的并行化

[英]Java JSONArray and Parallelization of iteration

I have a piece of code that I would like to parallelize as they are independent operations - 我有一段要并行化的代码,因为它们是独立的操作-

        List<StockQuote> topGainers = new ArrayList<StockQuote>();
        JSONObject jsonObject = (JSONObject)new JSONParser().parse(
                new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
        JSONArray dataArray = (JSONArray) jsonObject.get("data");

        //Parallelize the for loop
        for(int iter=0;iter<dataArray.size();iter++) {
            JSONObject temp = (JSONObject) dataArray.get(iter);
            System.out.println(temp.get("symbol"));
            //getQuote function has network calls. 
            //Serial implementation makes it take too much time
            topGainers.add(this.getQuote((String)temp.get("symbol")));
        }

        return topGainers;

How can this piece of code be parallelized? 这段代码如何并行化? Is ArrayList and its Add operation threadsafe? ArrayList及其添加操作线程安全吗?

I tried this - 我试过了-

        int size = dataArray.size();
        ForkJoinPool forkJoinPool = new ForkJoinPool(size);
        forkJoinPool.submit(() ->
        IntStream.range(1, size).parallel().filter( (IntPredicate)i -> { 
        JSONObject temp = (JSONObject) dataArray.get(i);
            System.out.println(temp.get("symbol"));
            try {
                System.out.println(temp.get("symbol"));
                topGainers.add(this.getQuote((String)temp.get("symbol")));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        return true;}));

I got the topGainers array as empty 我得到的topGainers数组为空

ArrayList is not a Synchronized collection. ArrayList不是Synchronized集合。 So, ArrayList#add is not thread-safe. 因此, ArrayList#add不是线程安全的。 Use CopyOnWriteArrayList instead which is thread safe. 使用CopyOnWriteArrayList代替它是线程安全的。 Java-8 provided us some excellent feature one of those is parallelStream over the collection. Java-8为我们提供了一些出色的功能,其中之一是集合上的parallelStream So you can take advantage of that. 因此,您可以利用它。 However, you are always free to create your own thread pool and execute the task if it gives you more benefit. 但是,如果它给您带来更多好处,您总是可以自由创建自己的线程池并执行任务。

Below example may help you 以下示例可能对您有帮助

    CopyOnWriteArrayList<StockQuote> topGainers = new CopyOnWriteArrayList<>();
    dataArray.parallelStream().forEach(e->{
        JSONObject temp = (JSONObject) dataArray.get(iter);
        System.out.println(temp.get("symbol"));
        //getQuote function has network calls. 
        //Serial implementation makes it take too much time
        topGainers.add(this.getQuote((String)temp.get("symbol")));
    });

You cloud also use Collections#synchronizedList . 您的云还使用Collections#synchronizedList

Answer from the question 1 from comment: dataArray.parallelStream().forEach will iterate over the list in parallel. 注释1对问题1的回答: dataArray.parallelStream().forEach将并行遍历该列表。

Answer to your question 2 from comment : 通过评论回答您的问题2:

   dataArray.parallelStream().forEach(e->{
        JSONObject temp = (JSONObject) dataArray.get(iter);
        System.out.println(temp.get("symbol"));
        //getQuote function has network calls. 
        //Serial implementation makes it take too much time
        if (some condition here) {
           throw new YourException("Your exception messge");
         }
        topGainers.add(this.getQuote((String)temp.get("symbol")));
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM