|
|
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Есть основной поток, который собирает некую информацию в list и отдает ее сейвить в отдельный поток. Пока информация сохраняется, основной поток продолжает работу. Как только пришло время снова сохранить информацию, он проверяет наличие запущенных потоков, если есть - ждет их окончания. Дело в том, что getActiveCount() в javadoc написано, что авторreturns the approximate number of threads that are actively executing tasks. и меня это беспокоит. Как правильно решить подобную задачу с помощью ExecutorService? Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 15:36:42 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
ОзверинКак только пришло время снова сохранить информацию, он проверяет наличие запущенных потоков, если есть - ждет их окончания . А зачем это? Не проще ли в очередь положить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 15:40:47 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, это к вопросу о парсинге файла на 30КК записей ;) Так как скорость чтения много превосходит скорость записи, то есть подозрение что рано или поздно я упрусь в то, что надо будет ждать завершения потока, чтобы опять в outOfMemory не прийти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 15:51:42 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Озверин, мелкий вопрос. А зачем тебе читать быстрее записи? авторТак как скорость чтения много превосходит скорость записи она у всех превосходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:00:01 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123Озверин, мелкий вопрос. А зачем тебе читать быстрее записи? авторТак как скорость чтения много превосходит скорость записи она у всех превосходит. Отличный вопрос. И ответ такой же: хочу оптимизировать общее время на сумму операций, т.е. чтобы издержка на ожидание записи была минимальной. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:03:53 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Я тоже придерживаюсб мнения, что тут Executor лишний, тут классическая схема - один потребитель один производитель. А такая ситуация разруливается через расшаренную queue, в java concurrency in practice даже пример есть, там все потоки скидывают таски по логированию в queue, а потребитель читает таски и пишет в базу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:05:34 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Озверинэто к вопросу о парсинге файла на 30КК записей ... чтобы опять в outOfMemory не прийти.Реализовать циклический буфер "поверх массива фиксированного размера"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:05:52 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
По-моему при создании ThreadPoolExecutor нужно использовать ArrayBlockingQueue. В этом случае, если очередь заполнена до определенного предела, то вызывающий поток заблокируется, пока рабочие потоки не освободят место в очереди. Не совсем то что вы просили, но, по-моему, решает ту же самую задачу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:06:01 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
забыл никЯ тоже придерживаюсб мнения, что тут Executor лишний, тут классическая схема - один потребитель один производитель. А такая ситуация разруливается через расшаренную queue, в java concurrency in practice даже пример есть, там все потоки скидывают таски по логированию в queue, а потребитель читает таски и пишет в базу. executorService так же имеет queue со всеми вытекающими. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:08:42 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
авторПо-моему при создании ThreadPoolExecutor нужно использовать ArrayBlockingQueue. В этом случае, если очередь заполнена до определенного предела, то вызывающий поток заблокируется, пока рабочие потоки не освободят место в очереди. Не совсем то что вы просили, но, по-моему, решает ту же самую задачу. Вы правы, но я так понимаю Озверин хочет избежать блокирования основного воркера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:09:46 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПо-моему при создании ThreadPoolExecutor нужно использовать ArrayBlockingQueue. В этом случае, если очередь заполнена до определенного предела, то вызывающий поток заблокируется, пока рабочие потоки не освободят место в очереди. Не совсем то что вы просили, но, по-моему, решает ту же самую задачу. дело в том, что и при service.execute() насколько я понял ThreadPoolExecutor если нет свободных потоков, ставит таску в ожидание(по умолчанию я так глянул засовывает ее в LinkedBlockingQueue и как только появляется свободный поток - исполняет таску. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:10:18 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
забыл никВы правы, но я так понимаю Озверин хочет избежать блокирования основного воркера. Наоборот. При определенном размере очереди, нужно сказать читающим потокам - хватит читать. Память засрана. Дайте писателям сбросить очередь в вывод. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:11:32 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
авторexecutorService так же имеет queue со всеми вытекающими. Если постараться, то можно сюда и Fork/Join прикрутить, вопрос зачем-? Я придерживаюсь мнения что использования инструмента не по назначению, только запутывают код, стандартным решением тут является расшаренная queue, но вы конечно вольны делть как хотите. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:11:33 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
1. Из потока ничего не хочу получать 2. Чем плоха очередь, я на запись передаю целую тучу данных(пусть это будет не 1 поток, а 10 параллельных) в сумме эти записи , не следи я за кол-вом , завалят меня в outOfMemory. Вывод : рано или поздно у меня возникнет проблема с тем, чтобы ожидать завершения 1го (или более) потоков, чтобы по их завершени GC мог сделать свое грязное дело. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:12:13 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
авторНаоборот. При определенном размере очереди, нужно сказать читающим потокам - хватит читать. Память засрана. Дайте писателям сбросить очередь в вывод. А, ну да, тогда вы абсолютно правы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:12:22 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
авторЧем плоха очередь, я на запись передаю целую тучу данных(пусть это будет не 1 поток, а 10 параллельных) в сумме эти записи , не следи я за кол-вом , завалят меня в outOfMemory. Вывод : рано или поздно у меня возникнет проблема с тем, чтобы ожидать завершения 1го (или более) потоков, чтобы по их завершени GC мог сделать свое грязное дело. Говорили же что есть такое понятие как bounded queue, в частности реализована в ArrayBlockingQueue ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:13:32 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Озвериндело в том, что и при service.execute() насколько я понял ThreadPoolExecutor если нет свободных потоков, ставит таску в ожидание(по умолчанию я так глянул засовывает ее в LinkedBlockingQueue и как только появляется свободный поток - исполняет таску. Почитайте JavaDoc к ThreadPoolExecutor. Так как вы создаёте через фабрику - Executors, то там нет заготовки для ArrayBlockingQueue. LinkedBlockingQueue - как раз, и есть бесконечная очередь. Поэтому и не блокируется вызывающий поток. Очередь нужно заменить на конечную и всё. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:13:49 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Blazkowiczзабыл никВы правы, но я так понимаю Озверин хочет избежать блокирования основного воркера. Наоборот. При определенном размере очереди, нужно сказать читающим потокам - хватит читать. Память засрана. Дайте писателям сбросить очередь в вывод. т.е. для executorService делать что то вроде executorService.getQueue() и работать с ней уже? Я просто именно с новыми средствами java мало работал по многопоточности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:13:54 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
ОзверинЕсть основной поток, который собирает некую информацию в list и отдает ее сейвить в отдельный поток. я боюсь, что если мы говорим о субд , то ускорить запись методом: - потоки и распараллеливание = 1% - пакетная запись и оптимизация самой СУБД = 70% ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:14:24 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
BlazkowiczОзвериндело в том, что и при service.execute() насколько я понял ThreadPoolExecutor если нет свободных потоков, ставит таску в ожидание(по умолчанию я так глянул засовывает ее в LinkedBlockingQueue и как только появляется свободный поток - исполняет таску. Почитайте JavaDoc к ThreadPoolExecutor. Так как вы создаёте через фабрику - Executors, то там нет заготовки для ArrayBlockingQueue. LinkedBlockingQueue - как раз, и есть бесконечная очередь. Поэтому и не блокируется вызывающий поток. Очередь нужно заменить на конечную и всё. ок, этого хотел услышать, видимо ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:14:25 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123ОзверинЕсть основной поток, который собирает некую информацию в list и отдает ее сейвить в отдельный поток. я боюсь, что если мы говорим о субд , то ускорить запись методом: - потоки и распараллеливание = 1% - пакетная запись и оптимизация самой СУБД = 70% вполне вероятно. Но я не запись ускоряю, я сокращаю время ожидания записи. Насчет оптимизации самой субд - тоже стараюсь двигаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:15:34 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Озверинт.е. для executorService делать что то вроде executorService.getQueue() и работать с ней уже? Я просто именно с новыми средствами java мало работал по многопоточности. Блин, ну вроде же не rocket sience: Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:16:41 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123ОзверинЕсть основной поток, который собирает некую информацию в list и отдает ее сейвить в отдельный поток. я боюсь, что если мы говорим о субд , то ускорить запись методом: - потоки и распараллеливание = 1% - пакетная запись и оптимизация самой СУБД = 70% Петро, а ты я знаю хибером увлекся, пытался работать не с Рсубд+хибер?) Какие нить mongoDb и тд пробовал?) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:16:54 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
ОзверинНо я не запись ускоряю, я сокращаю время ожидания записи. ты не думал, что выше фраза - это анекдот от профи. Смысл фразы не раскрыт :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:17:43 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
ОзверинПетро, а ты я знаю хибером увлекся, пытался работать не с Рсубд+хибер?) Какие нить mongoDb и тд пробовал?) неперспективно, поэтому тока хибер. Если приготовить обычную БД, то другая не понадобится. ЗЫ. Да и потом - куда тебе торопится в записи для твоей задачи? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:20:04 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
счас посмотрю скорости записи БД (где-то было) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:21:05 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123ОзверинПетро, а ты я знаю хибером увлекся, пытался работать не с Рсубд+хибер?) Какие нить mongoDb и тд пробовал?) неперспективно, поэтому тока хибер. Если приготовить обычную БД, то другая не понадобится. ЗЫ. Да и потом - куда тебе торопится в записи для твоей задачи? :) Времени жалко ;)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:24:16 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123счас посмотрю скорости записи БД (где-то было) у меня MySQL 5.1 запись в базу из 2х таблиц: tbl1: key(bigint, varchar(25), varchar(100) tbl2: logrow(biging, varchar(255), varchar(512), varchar(2048), varchar(512), varchar(512), key_id) ps = createPreparedStatement(); ps.addBatch(); ps.executeBatch(); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:26:26 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
ОзверинВремени жалко ;)) ВИ без ОРМ - быстрее всего СУБД пишет файл своего формата - а) все читатели его готовят - б) субд одним махом его заберёт и моргнуть не успеешь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:26:50 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
вот, как обещал, для размышлений: Iskander Код: plaintext 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:34:33 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123ОзверинВремени жалко ;)) ВИ без ОРМ - быстрее всего СУБД пишет файл своего формата - а) все читатели его готовят - б) субд одним махом его заберёт и моргнуть не успеешь. Ход мысли не очень понял. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:34:52 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Petro123, про индексы и ежу понятно. @ManyToOne(cascade = CascadeType.ALL) key.id->logrow.key_id. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:36:50 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Озверин, >Ход мысли не очень понял. У каждой субд есть утилита или API для массовой закачки данных. Она отключает все тормоза у себя и обратно включает после заливки. Для MySQL поспрошай - я не в курсе. Один из вариантов давно делал. ~ 50 K или файл 500 мегов /topic/103823 т.е. это ещё быстрее чем пример выше без индексов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:42:31 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
посмотрел кстати LinkedBlockingQueue, на самом деле в конструкторе можно указать capacity, и тогда она станет ограниченной, вроде linkedQueue должна пошустрее работать чем ArrayBlockingQueue. Также посмотрел Java Concurrency in Practice - ваш пример есть в 7 главе, там авторы обращают внимание, что необходимо продумать, как грамотно остановить логирующий поток, весьма занимательно, если есть время - почитайте, там все очень хорошо расписано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:43:56 |
|
||
|
ExecutorService
|
|||
|---|---|---|---|
|
#18+
Ок, спасибо всем. По поводу "Java Concurrency in Practice" - как раз листаю ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2012, 16:52:34 |
|
||
|
|

start [/forum/topic.php?all=1&fid=59&tid=2132505]: |
0ms |
get settings: |
12ms |
get forum list: |
25ms |
check forum access: |
7ms |
check topic access: |
7ms |
track hit: |
74ms |
get topic data: |
22ms |
get forum data: |
5ms |
get page messages: |
95ms |
get tp. blocked users: |
3ms |
| others: | 376ms |
| total: | 626ms |

| 0 / 0 |
