Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Блокировка обращений к коллекции |
Автор: novichiok 25.10.2011, 15:05 | ||||
Здравствуйте. У меня такая проблема: В приложении множество потоков бегают случайный образом по MultiValueMap у которой в качестве value используется какой-то Collection. Эти потоки берут из Map'а коллекцию, извлекают из неё элемент,удаляют его из коллекции и обрабатывают. Если коллекция пустая то поток сабмитит таск на обновления коллекции для данного ключа в спец. пул. Этот пул содержит единственный поток, который и обновляет коллекции по ключу. Проблема заключается в том, что возможна такая ситуация когда несколько потоков достают по ключу одну и ту же коллекцию,она оказывается пустая, и сабмитят по сути один и тот-же таск на обновление. Я хочу этого избежать.Грубо говоря хотелось бы чтобы все выглядело так:
Так будет происходить в потоках-обработчиках. А в потоке обновителе что-то в этом роде:
Вопрос: как такой функционал реализовать правильно? (отнаследоваться от какой-то коллекции и сделать volatile флаг lock. как-то сильно просто) + Учитывая специфику задачи посоветуйте,пожалуйста, collection для мапа? Беря во внимание что из коллекции элементы нужно удалять, как-то не хочется использовать для таких целей ArrayList, из-за возможных тормозов с System.arrayCopy(...) |
Автор: Stolzen 25.10.2011, 15:43 |
Думаю, что можно использовать ReentrantReadWriteLock, если я правильно все понял. |
Автор: novichiok 25.10.2011, 16:19 |
Ну я тоже так думал. А затем нашел одну лазейку,из-за которой отказался отеё использования, а именно - у меня ведь главная цель не допустить сабмита одинаковых тасков в пул(тасков на обновление одной и той же коллекции), и вот предположим ситуацию : - у меня *читающие* обращения к коллекции синхронизируются readLock'ом из readWriteLock() - *пишущие* writeLock'ом. Теперь предположим что 1 поток читает из очереди, обнаруживает что она пустая - сабмитит таск на выполенение, затем сразу же 2 поток опять читает из той же очереди и опять -она пустая, сабмитит таск на выполнение. Дело в том что есть *большая* вероятность того, что 2 поток-обработчик будет отрабатывать раньше чем *пишущий* таск из пула. ведь для того чтоб 2поток обработчик не смог даже читать из коллекции, для начала таск из пула должен начать в неё писать, тем самым залочив её даже на чтение. |