|
|
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
Добрый день, коллеги. Есть следующая задача. Необходимо реализовать обработчик событий. Что-то на подобии UIного диспатчера. Есть возможность регистрировать и удалять слушателей. Затем кидать события. Все события обрабатываются через слушателей в одном потоке. Сразу оговорюсь задача с собеседования, поэтому j.u.c.* просили не используется. Собственно вот мой вариант, просьба покритиковать. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2013, 12:52:39 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
Копирования коллекций на каждом чихе конечно сильно режет глаз. Но с другой стороны. раз вым запретили использовать j.u.c, наверное других вариантом и нет. Серьезное замечание только одно: для остановки диспатчера вы вызываете Thread.interrupt(). НО! У вас нет контроля за тем, какая-логика выполняется внутри листенера. Поэтому может получиться так, что внтури какого-нибудь листенера будет Thread.interrupted(), который очистит этот флаг. Как следствие - диспатчер не остановится. Решение такое: 1) Добавить волатильный флажок stopped, и выставлять его в true в методе stop(). В while цикле и при итерировании по листенерам проверять его. 2) Оставить Thread.interrupt(), что бы ускорить выход из потока в случае, если листенер заблокировался на чем-нибудь. Другое мелкое замечание: зачем вы руками бросаете InterruptedException, если оно никогда не уйдет за пределы вашей логики? В этом нет смысла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2013, 13:36:28 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
mikhail_zh, Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Зачем Event у и Listener у быть нестатическими вложенными классами Dispatcher ? То, что они нестатические --- вообще бред. То, что вложены в Dispatcher -- теоретически, допустимо, но в общем -- достаточно плохой дизайн, Event и Listener в общем-то никак не связаны с Dispatcher, последний их только использует. Dispatcher лучше бы НАСЛЕДОВАТЬ от Thread, а не агрегировать его. Ну и Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Как думаешь, как это работать-то будет ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 09:50:32 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
MasterZivЗачем Event у и Listener у быть нестатическими вложенными классами Dispatcher ? То, что они нестатические --- вообще бред. То, что вложены в Dispatcher -- теоретически, допустимо, но в общем -- достаточно плохой дизайн, Event и Listener в общем-то никак не связаны с Dispatcher, последний их только использует.С нестатическим event могу согласиться. Остальное - крайне спорные утверждения. Все зависит от того, как все это собираются использоваться. Если слушатели определяет исключительно разработчик - то их можно абсолютно спокойно оставить внутри Dispatcher, никакого криминала в этом нет. Если же их будет имплементировать юзер - тогда их действительно надо как минимум сделать static, а еще лучше вынести в отдельный класс. Все эти разговоры про "плохой дизайн" вложенных классов идут буквально из нескольких книжек, где авторы, не утруждая себя внятными объяснениями, утверждают: "Нуууууу, вобще вложенный классы использовать достаточно плохо ..." А с хрена ли их плохо использовать? Вы посмотрите на реализацию коллекций в Java - там все во вложенных классах. И ничего, никто не умер. Это абсолютно нормальная практика, когда дочерние сущности класса находятся внутри этого класса. MasterZivDispatcher лучше бы НАСЛЕДОВАТЬ от Thread, а не агрегировать его.Это вообще за гранью добра и зла. Без каких-то очень-очень-очень серьезных причин наследоваться от Thread категорически нельзя. Во-первых, потому что переопределив методы Thread можно что-то ненароком сломать (например, getId()). А во-вторых, самое главное: зачем? Зачем наследоваться от Thread ? В задаче автора на то нет ни одной причины. Стандартная практика - implements Runnable. MasterZiv Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Как думаешь, как это работать-то будет ?А почему не будет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 10:22:22 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjv, MasterZiv Dispatcher лучше бы НАСЛЕДОВАТЬ от Thread, а не агрегировать его. Это вообще за гранью добра и зла. Без каких-то очень-очень-очень серьезных причин наследоваться от Thread категорически нельзя. Во-первых, потому что переопределив методы Thread можно что-то ненароком сломать (например, getId()). А во-вторых, самое главное: зачем? Зачем наследоваться от Thread? В задаче автора на то нет ни одной причины. Стандартная практика - implements Runnable. -- Это стандартная дебильная практика. Я на самом деле видал дофига примеров наследования от Runable. А, я наверное перепутал сутра Thread и Runable. Я имел в виду Runable. А доводы на счёт "ненароком сломать" -- ну ... не ломай. :-))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 10:37:27 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjv MasterZiv Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Как думаешь, как это работать-то будет ?А почему не будет? Входим в блок synchronized (events), events пуст, и мы начинаем ждать события на том же events. Но оно никогда не наступит, потому что взводится оно только в dispatchEvent(Event e), в другом блоке synchronized (events) , в который нельзя будет зайти, поскольку монитор events уже заблокирован. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 11:24:20 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
Кстати, вместо events.notifyAll(); должен быть events.notify(); Одно событие добавляется, какой смысл будить все ожидающие потоки ? достаточно одного. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 11:25:48 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
MasterZivВходим в блок synchronized (events), events пуст, и мы начинаем ждать события на том же events. Но оно никогда не наступит, потому что взводится оно только в dispatchEvent(Event e), в другом блоке synchronized (events) , в который нельзя будет зайти, поскольку монитор events уже заблокирован.Коллега, я вынужден констатировать, что вы не знаете, как работает wait/notify. Когда вызывается wait(), то поток освобождает захваченный монитор , и помещается в wait set этого монитора. Поэтому в другой блок synchronized(events) можно будет зайти . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:04:47 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
Спасибо за замечания: 1) Нестатичный Ивент класс - это косяк. Сделал их внутрениими просто для компактности. Вообще сам не злоупотребляю этим. 2) По воду остановки класса, это верно что нельзя опираться только на прерывание. Надо либо волотайл использовать либо атомарный булеан. 3) В цикле прохода по слушателям, действительно лучше break вставить вместо исключения на прерывание. Логику на исключениях лучше не строить. 4) Наследование от Thread и notify вместо notifyAll - очень спорные замечания. MasterZiv...поскольку монитор events уже заблокирован. при ожидании монитор разблокируется. ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:17:23 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
Не пойму что забред код или я что-то не понимаю. Почему вместо очереди вы используете ArrayList? Скорей всего тут нужна не просто очередь, а приоритетная очередь. Вот писал для себя очередь для обработки пакетов от клиента. Код: 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. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:31:16 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
Вам просто подогнать под свой Executor который можете сами написать с 1 потоком. Хотя мб я не понял задания. Так же не понял почему здесь: Код: java 1. 2. 3. 4. 5. 6. 7. Вы постоянно присваиваете новый ArrayList? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:34:18 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
mikhail_zh, Код: java 1. 2. 3. А где обработка исключения? wait бросает InterruptedException ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:50:20 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
greenpo1son , Коллега, а что у вас делает метод ExecutableQueue.run()? Выглядит он отвратительнейшим образом. И зачем у ваша очередь имплементирует Runnable? Без обид, но весь ваш код выглядит как очень кривой велосипед, написанный человеком, плохо разбирающимся в многопоточности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:50:23 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
MaxNevermind , Код: java 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:51:36 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
mikhail_zh, Код: 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. Мне кажется или если interrupt случиться в указанной строчке, то сообщения "Queue is stopped." вообще не будет записано? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:52:26 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjv MaxNevermind , Код: java 1. 2. 3. 4. Так он же при этом вообще остановиться, то есть диспатчер, а нужно чтобы он продолжил выполнение, так как добавилось новое событие ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:53:20 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
MaxNevermind , Когда поток интерраптается, это как правило означает, что он должен остановиться. А вы предлагаете проигнорировать interrupt(), и продолжить крутиться в цикле. Игнорирование интерраптов это как правило признак кривого кода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:55:09 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
MaxNevermindМне кажется или если interrupt случиться в указанной строчке, то сообщения "Queue is stopped." вообще не будет записано?"Кажется". Вызов interrupt() выставляет в треде специальный булевский флажок. А условие в первом цикле while этот флажок проверяет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:56:31 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjv MaxNevermind , Когда поток интерраптается, это как правило означает, что он должен остановиться. А вы предлагаете проигнорировать interrupt(), и продолжить крутиться в цикле. Игнорирование интерраптов это как правило признак кривого кода. http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:57:30 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjvMaxNevermindМне кажется или если interrupt случиться в указанной строчке, то сообщения "Queue is stopped." вообще не будет записано?"Кажется". Вызов interrupt() выставляет в треде специальный булевский флажок. А условие в первом цикле while этот флажок проверяет. Ну да, флажок выставляется - цикл заканчивается - кэтч не срабатывает ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 12:58:44 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjv greenpo1son , Коллега, а что у вас делает метод ExecutableQueue.run()? Выглядит он отвратительнейшим образом. И зачем у ваша очередь имплементирует Runnable? Без обид, но весь ваш код выглядит как очень кривой велосипед, написанный человеком, плохо разбирающимся в многопоточности. Интересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю?? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 13:12:46 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
greenpo1soncdtyjv greenpo1son , Коллега, а что у вас делает метод ExecutableQueue.run()? Выглядит он отвратительнейшим образом. И зачем у ваша очередь имплементирует Runnable? Без обид, но весь ваш код выглядит как очень кривой велосипед, написанный человеком, плохо разбирающимся в многопоточности. Интересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю?? Или же вы не понимаете что такое ExecutableQueue? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 13:17:35 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
MaxNevermind http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html Не совсем понял, к чему эта ссылка. MaxNevermindНу да, флажок выставляется - цикл заканчивается - кэтч не срабатываетА, я невнимательно прочитал ваш комментарий. Вы акцентировали внимание на распечатку в логгер "queue is stopped". Да, согласен, не распечатается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 15:20:29 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
greenpo1sonИнтересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю?? Или же вы не понимаете что такое ExecutableQueue?Если честно - я понятия не имею, что такое ExecutableQueue. Но это не мешает мне утверждать, что ваш код нужно выкинуть. Есть такое понятие - code smell. Это когда даже не вникая в то, что делает код, можно сказать, что он неверный, отталкиваясь от косвенных признаков. Так вот, ваш код очень сильно "смеллит". Я даже не хочу писать конкретные ошибки - их слишком много, и нет смысла их исправлять. Давайте так - объясните вашу задачу. и я накидаю вам нормальное решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 15:24:02 |
|
||
|
Задача по многопоточности
|
|||
|---|---|---|---|
|
#18+
cdtyjvgreenpo1sonИнтересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю?? Или же вы не понимаете что такое ExecutableQueue?Если честно - я понятия не имею, что такое ExecutableQueue. Но это не мешает мне утверждать, что ваш код нужно выкинуть. Есть такое понятие - code smell. Это когда даже не вникая в то, что делает код, можно сказать, что он неверный, отталкиваясь от косвенных признаков. Так вот, ваш код очень сильно "смеллит". Я даже не хочу писать конкретные ошибки - их слишком много, и нет смысла их исправлять. Давайте так - объясните вашу задачу. и я накидаю вам нормальное решение. DOUBLE OMG. Нука хотябы одну ошибку в студию! Если вы даже не поняли что за класс перед вами , то что вы сможете объяснить ? Ссылаетесь не понятно на что. Код этот работает так: Например есть пул с 30 потоками. Приходит запрос ,в Селекторе читаем буффер и хандлим пакеты. Появились пакеты на отправку , добавляем их в эту очередь, при том это умная очередь которая способна распознать выполняются в ней пакеты или нет. То есть очередь не допустит что бы сразу 30 пакетов (запросов) не забрали все 30 потоков в пуле а достаточно что 1 поток обрабатывает всю очередь ... напишите мне альтернативу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2013, 16:03:36 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=210&tid=2128600]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
41ms |
get topic data: |
18ms |
get forum data: |
4ms |
get page messages: |
143ms |
get tp. blocked users: |
2ms |
| others: | 281ms |
| total: | 524ms |

| 0 / 0 |
