J'ai obtenu ConcurrentLinkedDeque que j'utilise pour les éléments push/pop synchronisés, et j'ai des tâches asynchrones qui prennent un élément de la pile et si cet élément a des voisins, il le pousse vers la pile.
Exemple de code:
private ConcurrentLinkedDeque<Item> stack = new ConcurrentLinkedDeque<>();
private ExecutorService exec = Executors.newFixedThreadPool(5);
while ((item = stack.pollFirst()) != null) {
if (item == null) {
} else {
Runnable worker = new Solider(this, item);
exec.execute(worker);
}
}
class Solider{
public void run(){
if(item.hasNeighbors){
for(Item item:item.neighbors){
stack.Push(item)
}
}
}
}
Je voudrais avoir une déclaration supplémentaire dans la boucle while qui répond à la question - "n'importe quelle tâche dans Executor fonctionne?"
Il n'y a pas de moyen propre de vérifier si tous les Runnables sont terminés si vous utilisez ExecutorService.execute(Runnable)
. Sauf si vous construisez un mécanisme pour le faire dans le Runnable lui-même (ce qui est bâclé à mon avis).
Au lieu de cela:
Utilisez ExecutorService.submit(Runnable)
. Cette méthode renverra un Future<?>
qui est un descripteur du résultat d'un Runnable
. Utiliser Futures fournit un moyen propre de vérifier les résultats.
Tout ce que vous avez à faire est de maintenir une liste des contrats à terme que vous soumettez, puis vous pouvez parcourir toute la liste des contrats à terme et soit:
A) attendre que tous les contrats à terme se fassent de manière bloquante ou
B) vérifier si tous les contrats à terme se font de manière non bloquante.
Voici un exemple de code:
List<Future<?>> futures = new ArrayList<Future<?>>();
ExecutorService exec = Executors.newFixedThreadPool(5);
// Instead of using exec.execute() use exec.submit()
// because it returns a monitorable future
while((item = stack.pollFirst()) != null){
Runnable worker = new Solider(this, item);
Future<?> f = exec.submit(worker);
futures.add(f);
}
// A) Await all runnables to be done (blocking)
for(Future<?> future : futures)
future.get(); // get will block until the future is done
// B) Check if all runnables are done (non-blocking)
boolean allDone = true;
for(Future<?> future : futures){
allDone &= future.isDone(); // check if future is done
}