Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Пулл потоков / 7 сообщений из 7, страница 1 из 1
23.12.2014, 16:43
    #38840843
Antipich
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
Добрый день.
Есть у меня задачка такая.

Есть набор команд в очереди. У команды есть проперти userId.
Необходимо выполнять эти команды в несколько потоков, максимальное количество которых N, при этом для одного userId ограничение по потокам M<=N.
Вот если бы не второе ограничение, то все понятно, берем ThreadPoolExecutor, переводим очередь команд в очередь Runnable и вперед.
Но вот как ограничить количество потоков по userId? При чем в идеале, если уже достигнуто максимальное количество потоков по M, то чтобы не тормозить остальных userId, эти команды должны как бы временно "пропускаться"(возможно просто отщиплять их в отдельную очередь и передавать ее работающим по этому userId потокам).
Понятное дело, что можно свелосипедить и сделать свой вариант пулла(к чему сейчас и склоняюсь, реализация тут вроде не особо замысловатая)
Но есть ли какие более стандартные способы для решения данной задачи? Заранее благодарю.
...
Рейтинг: 0 / 0
23.12.2014, 21:43
    #38841106
vimba
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
Кастомный пулл не нужен, достаточно кастомной очереди.
...
Рейтинг: 0 / 0
23.12.2014, 23:19
    #38841135
DEVcoach
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
1) Кастомный раннабл, который на старте инкрементит счетчик для текущего пользователя, на завершении в finally-блоке - декрементит.
2) Своя реализация BlockingQueue, которая пропускает элементы, у которых счетчик превысил лимит конкурентных задач для пользователя.
...
Рейтинг: 0 / 0
24.12.2014, 09:31
    #38841276
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
Antipich,

Вот тут, вроде, похожее обсуждали.
http://rsdn.ru/forum/java/5878107
...
Рейтинг: 0 / 0
24.12.2014, 11:38
    #38841477
DEVcoach
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
BlazkowiczAntipich,
Вот тут, вроде, похожее обсуждали.
http://rsdn.ru/forum/java/5878107 Похожее, но не то. Здесь не более M задач, там не более одной. В последнем случае решений больше, и они проще.
...
Рейтинг: 0 / 0
24.12.2014, 22:20
    #38842187
rfq
rfq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
Antipich,

Если бы каждая задач занимала отдельный поток, то, вероятно, вы бы завели семафор со значением M, на старте делали бы ему acquire, а перед выходом - release. При программировании задачами, когда задаче не разрешено блокироваться, алгоритм остается тот же самый, но реализация конечно нужна специфическая. К сожалению, в стандартной библиотеке нет асинхронных аналогов популярных средств синхронизации типа семафоров, но к счастью, их легко сделать своими руками.
Код: 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.
class AsyncSema {
   Executor threadPool;
   Queue input;
   int counter=M;

  // задача встает в очередь к семафору и забирает единицу ресурса
   synchronized void aquire(Runnable task) {
      if (counter==0) {
        input.add(task);
     } else {
        counter--;
        execute(task);
    }

  // ресурс освобождается и пропускает другую задачу
   synchronized void release() {
      if (M==0 && !input.isEmpty()) {
         execute(input.remove());
      } else {
         M++;
      }

   // чтобы задачи не забывали возвращать ресурс,
   // сделаем это за них
   private void execute(final Runnable task) {
      threadPool.execute(new Runnable(){
         try {
           task.run();
         } finally {
           release();
         }
      });
    }
     
    // теперь вместо threadPool.execute(task)
    // используем aSema.aquire(task);
}



Верояно, нужен еще один класс - коллекция семафоров, с методом execute, который будет извлекать userId из задачи, брать соответствующий семафор и посылать задачу ему.
...
Рейтинг: 0 / 0
24.12.2014, 22:27
    #38842189
rfq
rfq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пулл потоков
Опечатка, следует читать:
rfq
Код: java
1.
2.
3.
4.
5.
6.
   synchronized void release() {
      if (counter==0 && !input.isEmpty()) {
         execute(input.remove());
      } else {
         counter++;
      }
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Пулл потоков / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]