2016-03-31 27 views
-1

İki döngüm var. İç döngüde, bir Veri Tabanına bastım, sonucu aldım ve sonuçta bazı özel yöntemler (diğer özel yöntemleri çağırmayı içerir) gerçekleştiririm ve sonucu bir haritaya koyarım. Bu yaklaşım, herhangi bir tuş için null'u eklemek gibi bir soruna neden olur mu?Java 8 Bir haritayı paralel akışta güncelleme

İki iş parçacığı aynı değeri güncelleştirmez. Yani, hesaplanan key benzersiz olacaktır. "Ben birden çok iş parçacığı eşzamanlı karma haritaya ekleyebileceğiniz?"

Map<String,String> m = new ConcurrentHashMap<>(); 
     obj1.getProp().parallelStream().forEach(k1 -> { //obj.getProp() returns a list 
      obj2.parallelStream().forEach(k2-> { //obj2 is a list 

       String key = constructKey(k1,k2); 
      //Hit a DB and get the result 
      //Computations on the result 
      //Call some other methods 
       m.put(key, result); 
      }); 
     }); 

cevap

1

Sorunuz parça aşağı kaynar (Bu n kez döngüler halinde, n tuşları olacak) ve "veritabanına paralel olarak erişebilir miyim?"

ilk cevabı: temelde kullanan iki paralel akışlar sadece birden çok iş parçacığı üzerinde iç lambda başlatın: "evet", ikinci cevabı

"değişir" Ya biraz daha uzun olduğu yürütme havuzunda. Haritanın kendisine eklenmesi bir sorun değil, eşzamanlı karma haritanın ne için yapıldığı.

Veritabanıyla ilgili olarak, onu nasıl sorguladığınıza ve nesneyi hangi düzeyde paylaştığınıza bağlıdır. Her iş parçacığı için farklı bir bağlantıya sahip bir bağlantı havuzu kullanırsanız, muhtemelen iyi olacaktır. Çoğu veritabanında, bağlantıyı paylaşma ve iş parçacığı başına yeni bir bildirim alma da sorun değil. Bir ifadeyi paylaşmak ve yeni bir sonuç kümesi almak, oldukça fazla sayıda veritabanı sürücüsü için sorunlara yol açar.

2

Çevrim API'sini alternatif bir yazım olduğundan daha fazla anlayamadıkça Akış API'sini kullanmamalısınız. Genellikle, kodunuz bir akışta bir forEach içeriyorsa, kendinize bu görev için gerçekten en iyi çözüm olup olmadığını kendinize sormalısınız, ancak kodunuz bir iç içeforEach çağrı içeriyorsa, numarasını bilmeniz gerekir. Doğru olan şey değil.

Eşzamanlı bir haritaya eklediğinizde, sorunuzda olduğu gibi işe yarayabilir, ancak Stream API'sinin amacını bozar. obj.getProp() sonucu tipi ve obj2 tipi diziler olduğunda

Bunun yanı sıra, diziler yorumlarınız dediğin gibi, bir dere inşa etmek Arrays.stream(…) kullanmak zorunda, böylece bir parallelStream() yöntemi yoktur. Eğer

Map<String,String> m = 
    Arrays.stream(obj1.getProp()).parallel() 
     .flatMap(k1 -> Arrays.stream(obj2).map(k2 -> constructKey(k1, k2))) 
     .collect(Collectors.toConcurrentMap(key -> key, key -> { 
      //Hit a DB and get the result 
      //Computations on the result 
      //Call some other methods 
      return result; 
     })); 

bu yararı olarak uygulanabilir yapmak istiyorum ne

Eğer Collectors.toMap kullansalar bile olmayan bir eşzamanlı yaratarak çalıştığını fakat aynı zamanda, sadece paralel işleme daha iyi bir kullanım olduğunu Collectors.toConcurrentMap yerine Map; Çerçeve, onu güvenli bir şekilde üretmeye özen gösterecektir.

Eşzamanlı bir eşzamanlı bir eşleme için mutlaka eşzamanlı bir haritaya ihtiyacınız olmadıkça, aşağıdakilerden birini kullanabilirsiniz; hangisinin daha iyi performans göstereceği, tartışması bu cevabın kapsamını aşacak faktörlere bağlıdır.

Yani Akış API doğru kullanımı ile, ne olursa olsun, güvenli iş parçacığı olacak olan Map türü üretmek ve kalan soru bankası erişim as already explained in this answer birçok faktör bağlıdır, hangi, iplik güvenli olup olmadığıdır Sorunuza dahil etmediğiniz için, buna cevap veremeyiz.

+0

Özür dilerim. Bu bir liste değil bir dizi – Ashwin

+0

Senin cevabından, list.parallelStream – Ashwin

+0

ile Arrays.stream dönüştürebilirsiniz Evet, 'Arrays.stream (array) .parallel() 'veya' liste kullanıp kullanmadığın önemli değil .parallelStream() ', akış işleminin mantığı aynıdır. Tüm akış işlemi paralel modda çalışacaktır, dolayısıyla iç akış için 'list.stream()' veya 'list.parallelStream()' kullanıp kullanmadığınız önemli değildir. – Holger