tamamlandığında, bir dizi ileti dizisinden sonuçları işlemek için bir CompletionService kullanmak istiyorum. Kullanıma hazır olduklarında gelecekteki nesneleri almak için bir döngüde hizmetim var, ancak tüm iş parçacıklarının ne zaman tamamlandığını (ve dolayısıyla döngüden çıkıp çıkamayacağını) belirlemenin en iyi yolunu bilmiyorum:Bir Tamamlama Hizmeti'nin sonuçları teslim etmeyi bitirdiğinde nasıl bilinir?
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class Bar {
final static int MAX_THREADS = 4;
final static int TOTAL_THREADS = 20;
public static void main(String[] args) throws Exception{
final ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(MAX_THREADS);
final CompletionService<Integer> service = new ExecutorCompletionService<Integer>(threadPool);
for (int i=0; i<TOTAL_THREADS; i++){
service.submit(new MyCallable(i));
}
int finished = 0;
Future<Integer> future = null;
do{
future = service.take();
int result = future.get();
System.out.println(" took: " + result);
finished++;
}while(finished < TOTAL_THREADS);
System.out.println("Shutting down");
threadPool.shutdown();
}
public static class MyCallable implements Callable<Integer>{
final int id;
public MyCallable(int id){
this.id = id;
System.out.println("Submitting: " + id);
}
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
System.out.println("finished: " + id);
return id;
}
}
}
ThreadPoolExecutor öğesinin durumunu denetlemeyi denedim, ancak getCompletedTaskCount ve getTaskCount yöntemlerinin yalnızca yaklaşık değerler olduğunu biliyorum ve bunlara güvenmemeliyim. Tamamlandıktan sonra tüm Vadeli İşlemleri tamamladığımı garanti etmenin daha iyi bir yolu var mı?
Düzenleme: Nobeh sağlanan bağlantı ve this link Hem önermek o zaman take çağırarak, gönderilen görevlerin sayısını sayma() birçok kez, gitmek yoludur. Tamamen CompletionService veya Executor'a iade edilmek için ne bırakıldığını sormanın bir yolu olmadığına şaşırdım.
Teşekkürler, nobeh. "Thread (int tasksHandled = 0; tasksHandled
API'daki örnek, arka arkaya take() n kere yürütme ile aynı yaklaşımı kullanır. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorCompletionService.html –
CompletionService'den sonuçlar farklı bir iş parçacığında Exector'a gönderilen görevlerden alınmışsa, bu iş parçacığı güvenli midir? – raffian