Pull to refresh

Comments 17

По коду:
1. BacklogThreadPool.sequence инкрементится непотокобезопасно, лучше убрать volatile, а getSequence сделать static synchronized. Хотя здесь это, конечно, совершенно некритично.
2. Я на 100% уверен, что CasCounter будет работать медленнее, поскольку CAS всё равно эмулируется через synchronized, а операция сложения явно проще чем сравнение и условное присваивание.

Ну и, естественно, вертящийся на языке вопрос: зачем в реальной жизни нужно условие не использовать java.util.concurrent кроме как для поддержки чего-нибудь на Java 1.4
В лабораторных работах, в тестовых заданиях бывает просят не пользоваться частью библиотек.
1. поправил
2. я хотел показать как работает Atomic, CasCounter действительно работает медленее, но не сильно.

Почему такое условие было поставленно не знаю, думаю это задание либо на собеседование, либо по учебе, и хотят посмотреть как человек понимает многопоточность.
Да, согласен, условие жестокое :)
Насколько я вижу у Вас задача «работа с файловой системой» и задача «парсинг имен» обрабатываются однотипно. Очевидно (если отбросить файловый кеш операционной системы), что чтение списка файлов будет являться бутылочным горлышком. Поэтому лучше будет читать список файлов последовательно в отдельном потоке, а парсинг имен производить в пуле потоков.
Да, в принципе этот подход возможен, но процент времени, которое тратит процессор на IO и на парсер не соизмерими IO >> parse, Тем более это сильно зависит от OS, к примеру win7 в принципе держит кэш файловой системы, поэтому производительность однопоточного решения будет менее выгодно.
Ну это зависит от того в каких условиях чаще всего будет применяться алгоритм. Попробуйте запустить Ваше решение на компакт-диске с большим количеством файлов/папок ;)
Вообще думаю лучше всего было-бы использовать средства фильтрации ОС если условие совпадения endswith.
Все правильно, тут надо решение подводить под конкретную ситуацию, к примеру если это запустить на SSD, то мне кажется, что однопоточное решение на IO будет медленней, чем многопоточное, но если запускать на CD/DVD, то однопоточное решение будет быстрее.
UFO just landed and posted this here
была описана как работает в принципе Atomic, как работает JIT уже не так важно. К примеру на одном собеседовании у меня однажды спросили именно как работает Atomic, ответ — JIT в момент компиляции разворачивает вызовы Unsafe в конкретные наборы команд на целевой архитектуре врят ли бы устроил :)
UFO just landed and posted this here
Не совсем понял, как вы изначально добавляете таски — берете первую директорию и примерно делите её список поддиректорий на N частей, где N = кол-во ядер процессора * 4?
По поводу проблемы аггрегации результатов с выполненных тасков — тут вроде бы подходит способ, пропагандируемый fork-join framework.
Удивился что не используется Semaphore в worker'ах, потом вспомнил про запрет на util.concurrent.
Хотя он достаточно легко реализуется через wait-notify, и отлично ложится на задачу,
реализация ThreadPool'а получилась бы намного короче и понятнее.
public class WalkinTask1 implements BacklogTask
а где взять интерфейс BacklogTask?
почему-то все потоки весят в wait после того как все поддиректории обработаны.
выяснил, что проблема в последней строке этого куска кода (класс BacklogWorker):
for (int i = 0; i < INITIAL_CAPACITY && i < size; i++) {
workQueue.add(backlog.poll());
}
backlog.clear();

да и странно как-то… выбрали из бэклога INITIAL_CAPACITY задач (в случае, если их больше там), а остальные удалили. После того как закомментировал эту строку, программа завершается корректно.

правда и результаты другие. если взять время выполнения createSingleWalkinTask за 100%, то createWalkingTask выполняется за 87%, а createWalking1Task — 83% времени.
Sign up to leave a comment.

Articles