Comments 17
По коду:
1. BacklogThreadPool.sequence инкрементится непотокобезопасно, лучше убрать volatile, а getSequence сделать static synchronized. Хотя здесь это, конечно, совершенно некритично.
2. Я на 100% уверен, что CasCounter будет работать медленнее, поскольку CAS всё равно эмулируется через synchronized, а операция сложения явно проще чем сравнение и условное присваивание.
Ну и, естественно, вертящийся на языке вопрос: зачем в реальной жизни нужно условие не использовать java.util.concurrent кроме как для поддержки чего-нибудь на Java 1.4
1. BacklogThreadPool.sequence инкрементится непотокобезопасно, лучше убрать volatile, а getSequence сделать static synchronized. Хотя здесь это, конечно, совершенно некритично.
2. Я на 100% уверен, что CasCounter будет работать медленнее, поскольку CAS всё равно эмулируется через synchronized, а операция сложения явно проще чем сравнение и условное присваивание.
Ну и, естественно, вертящийся на языке вопрос: зачем в реальной жизни нужно условие не использовать java.util.concurrent кроме как для поддержки чего-нибудь на Java 1.4
В лабораторных работах, в тестовых заданиях бывает просят не пользоваться частью библиотек.
1. поправил
2. я хотел показать как работает Atomic, CasCounter действительно работает медленее, но не сильно.
Почему такое условие было поставленно не знаю, думаю это задание либо на собеседование, либо по учебе, и хотят посмотреть как человек понимает многопоточность.
2. я хотел показать как работает Atomic, CasCounter действительно работает медленее, но не сильно.
Почему такое условие было поставленно не знаю, думаю это задание либо на собеседование, либо по учебе, и хотят посмотреть как человек понимает многопоточность.
Да, согласен, условие жестокое :)
Насколько я вижу у Вас задача «работа с файловой системой» и задача «парсинг имен» обрабатываются однотипно. Очевидно (если отбросить файловый кеш операционной системы), что чтение списка файлов будет являться бутылочным горлышком. Поэтому лучше будет читать список файлов последовательно в отдельном потоке, а парсинг имен производить в пуле потоков.
Да, в принципе этот подход возможен, но процент времени, которое тратит процессор на IO и на парсер не соизмерими IO >> parse, Тем более это сильно зависит от OS, к примеру win7 в принципе держит кэш файловой системы, поэтому производительность однопоточного решения будет менее выгодно.
Ну это зависит от того в каких условиях чаще всего будет применяться алгоритм. Попробуйте запустить Ваше решение на компакт-диске с большим количеством файлов/папок ;)
Вообще думаю лучше всего было-бы использовать средства фильтрации ОС если условие совпадения endswith.
Вообще думаю лучше всего было-бы использовать средства фильтрации ОС если условие совпадения endswith.
UFO just landed and posted this here
Не совсем понял, как вы изначально добавляете таски — берете первую директорию и примерно делите её список поддиректорий на N частей, где N = кол-во ядер процессора * 4?
По поводу проблемы аггрегации результатов с выполненных тасков — тут вроде бы подходит способ, пропагандируемый fork-join framework.
По поводу проблемы аггрегации результатов с выполненных тасков — тут вроде бы подходит способ, пропагандируемый fork-join framework.
Удивился что не используется Semaphore в worker'ах, потом вспомнил про запрет на util.concurrent.
Хотя он достаточно легко реализуется через wait-notify, и отлично ложится на задачу,
реализация ThreadPool'а получилась бы намного короче и понятнее.
Хотя он достаточно легко реализуется через wait-notify, и отлично ложится на задачу,
реализация ThreadPool'а получилась бы намного короче и понятнее.
public class WalkinTask1 implements BacklogTask
а где взять интерфейс BacklogTask?
почему-то все потоки весят в wait после того как все поддиректории обработаны.
выяснил, что проблема в последней строке этого куска кода (класс BacklogWorker):
да и странно как-то… выбрали из бэклога INITIAL_CAPACITY задач (в случае, если их больше там), а остальные удалили. После того как закомментировал эту строку, программа завершается корректно.
правда и результаты другие. если взять время выполнения createSingleWalkinTask за 100%, то createWalkingTask выполняется за 87%, а createWalking1Task — 83% времени.
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.
Multithreading in practice