2012-02-26 33 views
6

Aynı anda bir Java yineleyicisi üzerinde çalışıyorum, ancak bunu yapmak için en iyi yolu ile sorunları yaşıyorum.Java Iterator Concurrency

Eşzamanlı olarak herhangi bir şey yapmaya çalışmadığım yerde neyim var.

Long l;  
Iterator<Long> i = getUserIDs(); 

while (i.hasNext()) { 
    l = i.next(); 

    someObject.doSomething(l); 
    anotheObject.doSomething(l); 
} 

Ben sigara yineleyici nesnelerde yapıyorum şeyler arasında hiçbir yarış koşulları olmalı, bu yüzden bu konuda çok çabaya gerek yok. Sadece sıralı olarak yapmamakla yineleyiciden geçmenin ne kadar sürdüğünü hızlandırmak isterim.

Şimdiden teşekkürler.

cevap

4

Bir çözüm, işinizi paralel hale getirmek için bir yürütücüyü kullanmaktır.

Basit bir örnek:

ExecutorService executor = Executors.newCachedThreadPool(); 

Iterator<Long> i = getUserIDs(); 
while (i.hasNext()) { 
    final Long l = i.next(); 

    Runnable task = new Runnable() { 
     public void run() { 
      someObject.doSomething(l); 
      anotheObject.doSomething(l); 
     } 
    } 

    executor.submit(task); 
} 

executor.shutdown(); 

Bu durumda işini yapacak yineleyici her öğe için yeni bir iş parçacığı oluşturur. Executors sınıfında farklı bir yöntem kullanarak kaç iş parçacığı kullanıldığını ayarlayabilir veya işi uygun gördüğünüz şekilde alt bölümlere ayırabilirsiniz (örneğin, yöntem çağrılarının her biri için farklı bir Runnable).

5

A, iki yaklaşımı sunabilir:

  • bir iş parçacığı havuzu kullanın ve ürün işleme parçacığı kümesine yineleyici alınan sevk. Bu, yineleyici işlemlerini kendiliğinden hızlandırmayacaktır, çünkü bunlar tek bir iş parçacığında hala gerçekleşebilir, ancak gerçek işlemeyi paralelleştirecektir. Birden fazla segmente yineleme işlemini bölmek için

  • iterasyon oluşturulduğunda nasıl bağlı olarak, mümkün olabilir, her biri farklı bir Iterator nesne yoluyla ayrı bir iş parçacığı tarafından işlenecek. Örneğin, List.sublist(int fromIndex, int toIndex) ve List.listIterator(int index) yöntemlerine bir göz atın.

    Bu, yineleyici işlemlerinin paralel olarak gerçekleşmesine izin verir, ancak yinelemenin yinelenmesi gereken öğelerin hemen elde edilememesi nedeniyle, yinelemeyi bu şekilde bölümlemek her zaman mümkün olmaz.

  • Yineleme işlemleri bir veritabanına erişmek için gerekenler gibi pahalı veya yavaşsa, bir numara olarak, bunları doldurmak için yineleyiciyi kullanacak ayrı bir iş parçacığına ayırırsanız, bir çıktı artışı görebilirsiniz. BlockingQueue. Dağıtıcı iş parçacığı, bir sonraki öğeyi almak için yineleyici nesnesini beklemeden yalnızca sıraya erişmelidir.

bu durumda en önemli tavsiyem şudur: genellikle izleyeceği, "senin profil oluşturucu kullan" "zamanından önce optimize etmeyin". VisualVM gibi bir profiler kullanarak, herhangi bir performans sorununun nedenini karanlıkta çekmeden, kesin kesin olarak belirleyebilmeniz gerekir.

1

Java 7'yi kullanıyorsanız, yeni çatalı/birleştirmeyi kullanabilirsiniz; tutorial'a bakın.

Yalnızca iş parçacıkları arasındaki görevleri otomatik olarak ayırmakla kalmaz, aynı zamanda bazı iş parçacıkları diğer iş parçacıklarından daha erken bitirirse, diğer iş parçacıklarından bazı görevleri "çalabilir".

İlgili konular