All streams
Search
Write a publication
Pull to refresh
4
0
Юрий @Borlok

Java Software Engineer

Send message

Пул и так один. Смысл в том, что бы распределить задачи внутри одного пула и оптимизировать его работу. Просто мы с вами говорим о разном уровне абстракции и разных языках программирования. Вы говорите про конвейер, терминаторы, которые в текущем контексте были бы реализованы выше по иерархии. Получается, что по аллегории, в статье мы разбираем буквы из алфавита, а вы - слова)

Так же специфичная для Java и Fork Join pool, в данном контексте, вещь - это как работает этот фреймворк. Мы создаем пул, у пула есть потоки, которые он распределяет на разные ядра, и при делении задач на количество большее, чем доступно ядер, мы не создаем новые потоки, а помещаем задачи в очередь на исполнение. Это не относится к многопоточному программированию, потому здесь нет Thread's в явном исполнении и блокировок. В данном случае это просто изолированный юнит работы, который мы оптимизируем и разбираем преимущества распределения задач.

Здравствуйте! Жадный алгоритм присутствует внутри пула ForkJoinPool, если мы говорим про алгоритм кражи работы. Поправьте, пожалуйста, если это не так. Это его собственная оптимизация в дополнении к той, что пишем мы. 

Сначала распределяете на разные ядра самые тяжелые потоки, а потом освободившиеся загружаете более легкими и так пока пул задач не опустеет.

Напротив, я не распределяю самые тяжелые задачи на ядра. Статья о том, что бы показать преимущества равного распределения. И здесь распределяются задачи по типу 1-10, 2-9, 3-8 и тд. Каждый поток в пуле, имеет свою очередь задач, и по приходу новых даных, они добавляются в очередь задач, которая есть у каждого потока в пуле.

P.S. Тем не менее кое-где в коде есть место, где я написал абсолютно неверное распределение) Кому будет интересно, могут сами придумать правильное распределение)

В классе AsyncTwoPointerTask методе divide(), мы делаем подобие пула

if (asPool) { 
  MyPhaser.register(); 
  new AsyncTwoPointerTask(investors.subList(leftStart, leftEnd), threshold, parts, asPool).fork(); 
  new AsyncTwoPointerTask(investors.subList(rightStart, rightEnd), threshold, parts, asPool).fork(); 
}

И здесь мы как раз забиваем один поток самыми легкими задачами, второй самыми тяжелыми. А смысл статьи - так не делать)

Здравствуйте! Спасибо, что так объемно описали механизм работы, который используете.

Каждая инвестиция от каждого инвестора обрабатывается одинаковым образом

Тут вы несомненно правы. В задачах же мы обрабатываем именно инвесторов, а тяжестью, или неоднородностью, является именно количество инвестиций на одного инвестора. То есть когда мы берем инвестора с 0 инвестиций, он обрабатывается мгновенно. Когда берем инвестора со 120 инвестициями, он обрабатывается примерно за 120 мс.

Думаю у нас несостыковка понятий) Поправьте, если ошибаюсь, но похоже что заданиями или задачами у вас называется то, что у нас называется репликами микросервисов. Это некоторое подобие копий мини серверов, которые могут общаться друг с другом(могут и не общаться), работают изолированно, могут иметь собственную БД и выполняют узкоспециализированные задачи. Очередями выступают Kafka, RabbitMQ и им подобные.

Задачами в статье я называю RecursiveTask - классы из ForkJoin Framework в Java, в которых мы описываем задачу на выполнение, если она подходит под условия, если же не подходит, она делится на подзадачи.

P.S. У вас впечатляющие объемы данным)

Information

Rating
Does not participate
Location
Россия
Date of birth
Registered
Activity

Specialization

Backend Developer
Middle
Java
Java Spring Framework
Spring Boot
Restful WebServices
Hibernate
SQL
MySQL
Git
High-loaded systems