|
|
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Есть задача, которую желательно распараллелить, т.е. нужно запускать в неск. потоков, сделал тестовый пример: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. Все вроде нормально работает ), но т.к. нахожусь уровне ребенка, который из кубиков с буквами учится складывать слова, а то и вообще не понимает, что на кубиках буквы ) на вс. случай может кто подскажет, как правильно это реализуется (может стоит использовать какой-то готовый класс пула потоков, очереди и т.п.? По-моему как-то ненадежно выглядит "синхронизация" работы с счетчиком работающих потоков или volatile в данном случае достаточно (может лучше создать отдельный метод для инкре/декримента счетчика с синхронайзд, а то может вообще этот счетчик не нужен)?) В общем как? ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 16:07 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
JDS, 1) Прочить про стандартные Executors и ThreadPoolExecutor. 2) Прочитать про то как нужно именовать свойства, имхо "curr_working_threads" - ужас! 3) Так делать нельзя Код: java 1. 2. И это "public static volatile int" - вам не поможет. Почитай как нужно делать счётчик (и как это можно делать средствами и пакета java.util.concurrent.**) И что делает и зачем нужен "volatile" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 16:19 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
xifr , спасибо, направление понял ушел искать, читать. По поводу имен переменных, соглсен, длинновато, но вроде не противоречит соглашению "Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. Internal words start with capital letters. Variable names should not start with underscore _ or dollar sign $ characters, even though both are allowed. Variable names should be short yet meaningful. The choice of a variable name should be mnemonic- that is, designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided except for temporary "throwaway" variables. Common names for temporary variables are i, j, k, m, and n for integers; c, d, and e for characters." Ну может кроме Variable names should be short yet meaningful ) А народ пишет по-разному ): 30% number_favorite_news 12% NumberFavoriteNews 46% numberFavoriteNews 2% numberfavoritenews 2% nfn (мне _сейчас_ так удобнее) 8% Иной вариант. Мне диктует его язык разработки ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 16:35 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
JDSПо поводу имен переменных, соглсен, длинновато, но вроде не противоречит соглашению Из ссылки: переменные называем, как nameNameName константы называем, как NAME_NAME_NAME (причем константы по смыслу, а не static объекты) Про статистику, это скорее не про JAVA, а вообще в целом. Например у PL/SQL программистов действительно, как правило переменные идут в стиле name_name_name ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 16:41 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Никогда не наследуйтесь от класса Thread кроме случаев острой необходимости. До появления java.util.concurrency (j.u.c) рекомендовали использовать Runnable. http://docs.oracle.com/javase/tutorial/essential/concurrency/ Никогда не оставляйте пустых catch блоков. Прочитайте определение volatile и атомарных операций. На том же вашем любимом хабре полно статей по этой теме. Задачу в зависимости от требований можно решить тремя методами 1) Создать пул через Executors и кидать туда чего душе угодно 2) ForkJoinPool, если нужен Fork/Join http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html 3) ParallelStream, если задачу удобно решить через Stream API https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 16:47 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
JDS но вроде не противоречит соглашению Противоречит. JDS А народ пишет по-разному ): [/quot] Где там про Java? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 16:48 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Blazkowicz , тоже спасибо, по части замечаний в курсе, а по большей части спасибо за инфу куда копать. Про именование точно, это про веб похоже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 17:01 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
JDSЕсть задача, которую желательно распараллелить, т.е. нужно запускать в неск. потоков, сделал тестовый пример: как вариант : где ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); накидывает по одному заданию раз в секудну в очередь Queue<String> queue = new ConcurrentLinkedQueue<>(); (Задания можно брать из базы итд) ExecutorService executorService = Executors.newFixedThreadPool(3); в три потока разгребает нашу очередь ... в коде есть разные задержки , так же из потока возвращается Callable в котором можно передать какие то данные ... while (true) - можно заменить на scheduler.scheduleWithFixedDelay - в котором выполнять задания в n потоков асинхронно. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. Вывод : Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 19:05 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Atum1, Внутри ExecutorService есть своя очередь. Зачем ещё одну заводить? Так же стоит обратить внимание на Future/FutureTask. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 20:43 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
BlazkowiczAtum1, Внутри ExecutorService есть своя очередь. Зачем ещё одну заводить? Так же стоит обратить внимание на Future/FutureTask. Спешил. Хотел показать разные варианты. Да нужно переписать через futuretask ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2015, 22:02 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Blazkowicz вопрос а как этот шедулер переиспользует лямбду? в этом месте? Код: java 1. 2. 3. 4. 5. 6. 7. каждый раз создает новый экземпляр runnable ? сам ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 08:55 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Atum1каждый раз создает новый экземпляр runnable ? сам ? Вроде как нет, каждый раз не создаётся. Лямбды имеют поведение аналогичное анонимным классам, но реализация совершенно иная. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 09:09 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
BlazkowiczAtum1каждый раз создает новый экземпляр runnable ? сам ? Вроде как нет, каждый раз не создаётся. Лямбды имеют поведение аналогичное анонимным классам, но реализация совершенно иная. Два, но это тред какой-то, мы же явно создали экземпляр runnable - и по всем старым канонам его можно использовать только один раз в отдельном потоке ... один раз сказать ему старт и все ...?! и еще вопрос в тему про обработку исключений Код: java 1. 2. 3. как обрабатывать и перехватывать и возвращать в главный поток ? ведь если там целый стек таких вызовов асинхронный - то мы ничего не отловим и не увидим ...? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 10:11 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Atum1Два, но это тред какой-то, мы же явно создали экземпляр runnable - и по всем старым канонам его можно использовать только один раз в отдельном потоке ... один раз сказать ему старт и все ...?! Вопроса не понял. Каким ещё канонам и почему только один раз? Создавай сколько угодно потоков на одном Runnable. Что мешает? Atum1как обрабатывать и перехватывать и возвращать в главный поток ? ведь если там целый стек таких вызовов асинхронный - то мы ничего не отловим и не увидим ...? По-хорошему через Future можно получить исключение выполнения. Если без Future, когда они не нужны, то нужно создать свою обертку, которая перехватывает и логирует исключения. И запускать через неё. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 10:28 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Почитал про Executors, ThreadPoolExecutor и ForkJoinPool. Понял одно - сомнительно, что мне нужен именно пул потоков. Сам по себе пул потоков нужен именно для снижения издержек на создание самих этих потоков (аналогично как например и с пулом соединений с БД). То есть, если я в пул поставлю например сто задач, ограничив пул 5-ю потоками, то, как понял, все эти сто задач будут выполняться "одновременно", используя доступные потоки выполнения в пуле, что не совсем то, что мне нужно по-моему. Мне нужно просто, чтобы например постоянно выполнялось пять задач в пяти потоках, завершилась одна задача, добавился поток с новой задачей. Про ForkJoinPool пока не понял его глобальные отличия, декларируется, дескать он в полной мере использует многопроцессорность, упоминается в контексте не многопоточного программирования, а некоего "параллельного", а ThreadPoolExecutor не использует многопроцессорность? Или треды, которые реализуются через тот же Runnable-интерфейс все железно запускаются только на одном процессоре/ядре? Понял так же то, что реализаций может быть множество, но пока склонен остаться на немного поправленном примитивном решении: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 13:02 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
JDSПонял одно - сомнительно, что мне нужен именно пул потоков. Сам по себе пул потоков нужен именно для снижения издержек на создание самих этих потоков (аналогично как например и с пулом соединений с БД). ExecutorService это не пул потоков. Это именно ExecutorService. ThreadPoolExecutor это ExecutorService внутри которого используется пул потоков. JDSТо есть, если я в пул поставлю например сто задач, ограничив пул 5-ю потоками, то, как понял, все эти сто задач будут выполняться "одновременно", используя доступные потоки выполнения в пуле, что не совсем то, что мне нужно по-моему. Вы очень глубоко ошибаетесь. ExecutorService никак не может менять задачи в процессе выполнения, даже если они блокируются. Внутри ThreadPoolExecutor помимо пула потоков находится ещё и очередь. Все задачи, которые не выполняются, находятся в этой очереди. По мере завершения выполнения задач, новые поступают из этой очереди. JDSМне нужно просто, чтобы например постоянно выполнялось пять задач в пяти потоках, завершилась одна задача, добавился поток с новой задачей. ThreadPoolExecutor именно это и делает, с одной лишь разницей, что вместо создания нового потока он пере-использует освободившийся. JDSПро ForkJoinPool пока не понял его глобальные отличия, декларируется, дескать он в полной мере использует многопроцессорность, упоминается в контексте не многопоточного программирования, а некоего "параллельного", а ThreadPoolExecutor не использует многопроцессорность? Это просто удобный инструмент для реализации Fork/Join. Но с вашим букетом заблуждений, наверное, в него вникать рано. JDSИли треды, которые реализуются через тот же Runnable-интерфейс все железно запускаются только на одном процессоре/ядре? "Треды" не реализуются через Runnable-интерфейс. Потоки вообще не реализуются. Это такая сущность, которая исполняет код. Runnable это всего лишь часть кода. Про ядра в контексте Java можно для начала забыть. Ваше основное заблуждение в том что вы не можете отделить "задачу" от "потока". JDSПонял так же то, что реализаций может быть множество, но пока склонен остаться на немного поправленном примитивном решении: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Гениальный код. Ну, нафига такое писать??? JDS Код: java 1. 2. Чем больше код похож на английский язык, тем проще его читать. Не бойтесь полноименных идентификаторов. Код: java 1. 2. JDS Код: java 1. 2. 3. 4. 5. Запускать потоки из конструктора не безопасно, так как конструктор ещё не завершил исполнение, а поток уже имеет ссылку на объект и может с ним работать. Это чревато трудно-повторимыми косяками. JDS Код: java 1. 2. InterruptedException очень важный элемент при работе с задачами вроде вашей. Не стоит его игнорировать. У нас лет десять назад шеф обещал за пустые catch-и увольнять. JDS Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. Очень рекомендую прочесть Clean Code by Robert Cecil Martin. У вас имена переменных во многих случаях совершенно не отражают своего предназначения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 13:27 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
[quot JDS] JDSМне нужно просто, чтобы например постоянно выполнялось пять задач в пяти потоках, завершилась одна задача, добавился поток с новой задачей. ThreadPoolExecutor именно это и делает, с одной лишь разницей, что вместо создания нового потока он пере-использует освободившийся. Про ForkJoinPool пока не понял его глобальные отличия, декларируется, дескать он в полной мере использует многопроцессорность, упоминается в контексте не многопоточного программирования, а некоего "параллельного", а ThreadPoolExecutor не использует многопроцессорность? как один из примеров ForkJoinPool 17690278 когда у вас простая вычислительная задача - вы разбиваете интервал на части ,а потом в конце их нужно склеить Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 15:28 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
BlazkowiczExecutorService это не пул потоков. Это именно ExecutorService. ThreadPoolExecutor это ExecutorService внутри которого используется пул потоков. Спасибо за пояснение, понимаю конечно, да и не писал, что ExecutorService - это пул потоков. BlazkowiczВы очень глубоко ошибаетесь. ExecutorService никак не может менять задачи в процессе выполнения, даже если они блокируются. Внутри ThreadPoolExecutor помимо пула потоков находится ещё и очередь. Все задачи, которые не выполняются, находятся в этой очереди. По мере завершения выполнения задач, новые поступают из этой очереди. ... ThreadPoolExecutor именно это и делает, с одной лишь разницей, что вместо создания нового потока он пере-использует освободившийся. Действительно, к своей радости, оказался неправ (да и изначально надеялся, что так и должно быть, но неверно трактовал одно из предложений в чтиве) BlazkowiczЭто просто удобный инструмент для реализации Fork/Join. Но с вашим букетом заблуждений, наверное, в него вникать рано. Ок Blazkowicz"Треды" не реализуются через Runnable-интерфейс. Потоки вообще не реализуются. Это такая сущность, которая исполняет код. Runnable это всего лишь часть кода. Про ядра в контексте Java можно для начала забыть. Согласен, выразился некорректно, но не будем доводить до абсурда, предполагая, что человек не понимает сути слова "поток" в контексте топика ) BlazkowiczВаше основное заблуждение в том что вы не можете отделить "задачу" от "потока". Это ваше заблуждение насчет моего заблуждения (см. выше)) BlazkowiczГениальный код. Ну, нафига такое писать??? Мне тоже не нравится, можно и вообще бы обойтись скорее, одним AtomicInteger например, просто пока читал, зацепил этот пример, ну и воткнул, дабы оценить по пути как спецы JAVA воспримут код из букваря ) Понятно, что вариантов синхронизации может придумать много, а если использовать пул, то этот счетчик и вообще вроде как не нужен. BlazkowiczЗапускать потоки из конструктора не безопасно, так как конструктор ещё не завершил исполнение, а поток уже имеет ссылку на объект и может с ним работать. Это чревато трудно-повторимыми косяками. Полезный нюанс, спасибо, а Шилдту руки оторвать, чему детей учит ) (без шуток, согласен, есть такое дело) BlazkowiczInterruptedException очень важный элемент при работе с задачами вроде вашей. Не стоит его игнорировать. У нас лет десять назад шеф обещал за пустые catch-и увольнять. Абсолютно согласен и сам на практике не грешу этим, но стараюсь просто не писать лишнего, приводя примеры, так-то можно написать и логирование и черта лысого, зачем это в примере? В моем понимании, в нормальной ситуации человек итак не будет гасить эксепшн пустым блоком обработки. BlazkowiczОчень рекомендую прочесть Clean Code by Robert Cecil Martin. Спасибо, посмотрю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 15:40 |
|
||
|
В неск. потоков
|
|||
|---|---|---|---|
|
#18+
Atum1как один из примеров ForkJoinPool когда у вас простая вычислительная задача - вы разбиваете интервал на части, а потом в конце их нужно склеить Если под ForkJoinPool подразумевается именно разбивка задачи и дальнейшее склеивание результатов, видимо, само название и говорит об этом, то склеивание мне не нужно, т.е. с головой хватит обычного FixedThreadPool-а. Буду рад еще уточнениям, а так всем спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2015, 15:56 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=118&tid=2124932]: |
0ms |
get settings: |
8ms |
get forum list: |
21ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
54ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
63ms |
get tp. blocked users: |
1ms |
| others: | 217ms |
| total: | 385ms |

| 0 / 0 |
