1.ExecutorService executor=Executors.newFixedThreadPool(50);
Прост е и лесен за употреба. Можеш да го използваш, когато не се притесняваш за неограничени опашки(queues) от задачи (tasks),които могат да се изпълнят за по-малък интервал от време. Изпълняването на един Runnable или Callable task може да не чака друг такъв да се изпълни. Самото изпълняване крие low level детайлите (тези на по-ниско ниво) нa ThreadPoolExecutor-a.
Предпочитам този, когато става въпрос за малко task-ове и натрупването на такива в неограничените queue-та не натоварват memory-то и понижават изпълнението на системата. Ако имаш ограничения на процесора/Паметта поради претрупване на task-ове, бих ти препоръчал да използваш ThreadPoolExecutor с ограничение на капацитета и RejectedExecutionHandler да handle-ваш отхвърлянето на задачи.
2.CountDownLatch: Ти си инициализирал CountDownLatch с някакъв count. Този count се намалява от извикванията (call-овете) към countDown() метода. Предполагам,че декрементата я call-ваш в своя пуснат (Runnable) task по-късно. Thread-овете,чакащи този count да стане нула могат да call-нат един от await() методите. Call-ването блокира thread-а (нишката) докато count-a не стане нула. Този клас позволява на java thread-а да чака докато друг набор от thread-ове се завършат.
Използват се в следните случаи:
1). Когато искаш да достигнеш максимален паралелизъм: Понякога ние искаме да стартираме няколко thread-а по едно и също време,за да достигнем максимален паралелизъм.
2). Чакаме N thread-а да се завършат преди изпълняването.
3).Локация на зa така наречената мъртва точка (Deadlock) - Когато 2 thread-а се изчакват взаимно и никой не тръгва.
Можеш да видиш повече тук:
http://howtodoinjava.com/core-java/multi-threading/when-to-use-countdownlatch-java-concurrency-example-tutorial/
3.ThreadPoolExecutor: Осигурява ти повече контрол. Ако application-а е затлачен от няколко изчакващи runnable task-а, ще използваш
ограничено queue като избереш максимален капацитет. В момента в който queue-то стигне максимален капацитет, можеш да дефинираш RejectionHandler-а
Java ни дава 4 типа RejectedExecutionHandler-a :
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html
1. В default ТhreadPoolExecutor.AbortPolicy handler-а throw-ва runtime RejectedExecutionException при отхвърляне.
2. В ThreadPoolExecutor.CallerRunsPolicy thread-a,който се обръща (invoke-ва) , самият той изпълнява task-а.
3. В ThreadPoolExecutor.DiscardPolicy -то, task,който не може да бъде изпълнен, се drop-ва.
4. В ТhreadPoolExecutor.DiscardOldestPolicy ,пък,ако изпълняващия (executor-a) не е изключен, task-а най-отгоре на опашката се drop-ва, и изпълняването се преповтаря (което може пак да fail-не, каращо това пак да се преповтори).
Можеш да видиш тук за повече инфо :
http://letslearnjavaj2ee.blogspot.bg/2013/08/threadpoolexecutor-handler-policies-for.html
А ако искаш да симулираш CountDownLatch behaviour, трябва да call-неш invokeAll() метода.
4. Между другото 1 механизъм, който не си споменал е ForkJoinPool
http://tutorials.jenkov.com/java-util-concurrent/java-fork-and-join-forkjoinpool.html
Той е бил добавен в Java 7. ForkJoinPool-а е горе-долу като Java ExecutorService-а ,но има 1 разлика.
Fork-а прави така,че task-овете да могат да си поделят работата като трансформират тези task-ове в по-малки, които по-късно се пращат при
ForkJoinPool-а. Крадене на task-oве (task stealing) може да се случи във Fork-а когато свободните работещи thread-ове "крадат" task-ове от заетите в queue.
Java 8 сложиха още 1 API в ExecutorService-a (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html )
което да създава такъв pool за кражба на работа. Няма смисъл да правиш RecursiveTask и RecursiveAction, но пак можеш да си ползваш ForkJoinPool-а.
public static ExecutorService newWorkStealingPool()
Създава pool с work-stealing thread, използващ всички налични процесори като parallelism level-а който ти трябва.
По default ще си вземе някакъв набор от ядра на процесора като параметър за паралелизма. Ако имаш 8-ядрен процесор, можеш да process-ваш work task queue-to с 8 thread-а и т.н.