| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Threads & vectors |
| Автор: polakwilno 25.9.2006, 10:55 | ||
| Добрый день, Народ, помогите советом, как избавится от такой проблемы:
Проблема возникает, когда size() вернет, скажем, 5, а перед вызовом какойто thread удалит один из елементов. Как защитить вектор ТОЛЬКО ОТ УДАЛЕНИЯ - возможность добавления и редактирования должна остатся... |
| Автор: powerOn 25.9.2006, 11:13 | ||
|
| Автор: polakwilno 25.9.2006, 12:15 | ||||
synchronized() вроде разрешает в тотже момент времени использовать переменную только одному процессу, то есть пока будет выполнятся for цикл я не смогу просто изменить вектор или добавить новый элемент... Или я неправ? |
| Автор: batigoal 25.9.2006, 12:54 |
| В Java 5 есть пакет concurrent, который позволяет более гибко работать с многопоточностью. В частности, там есть класс ReadWriteLock, который позволяет отдельно блокировать чтение и запись. Но проблемы с апдейтом это не решает. Добавлено @ 12:56 На самом деле, я не понял, почему мы синхронизируем цикл for(), а не кусок кода с удалением. |
| Автор: polakwilno 25.9.2006, 13:05 | ||
Так тоже врятли поможет... Получит он размер вектора 5, а потом код с удалением заблокирует вектор, удалит 1 элемент и освободит веткор. А метод get опять-же будет пытатся взять несуществующий элемент... Попробую наверно про concurent почитать, может чего полезного найду... |
| Автор: polakwilno 25.9.2006, 14:25 | ||
Возможно сама идея правильная, но мне кажется появится много багов изза того что ктото чегото не сможет записать пока вектор будет заблокирован... Но конечно надеюсь, что все будет работать нормально Потестирую сервак 1-2 дня потом напишу что получилось ;) |
| Автор: LSD 25.9.2006, 14:28 | ||
Ну вообщем, да, тут будет почти полная блокировка. Если тебе надо блокировать тольку удаление, то придется писать свою коллекцию. |
| Автор: powerOn 25.9.2006, 14:34 | ||
мы синхронизируем не сколько цикл for, сколько участок кода работающий с объектом вектора. Вот и весь смысл. |
| Автор: polakwilno 25.9.2006, 15:22 | ||||
LSD, удаление как таковое я заблокировал... Сделал специяльные методы get() и setFree(), которые увеличивают/уменьшают счетчик процесов, которые в данный момент используют вектор. А thread который удаляет ненужные элементы вектора, смотрит равен-ли счетчик 0, если да то удаляет, иначе - пропускает. Пробовал сделать похожее с функцией size() - увеличить счетчик а потом уменьшить, но тут много нюансов - делаешь чтоб работало в 1 месте - не работает в другом... В принципе, если synchronized() не поможет придется както делать счетчик на size()... Придется очень много переделать, но зато реально добится нужного результата. Просто думал попробую решить стандартными средствами, без всяких наворотов... Хе хе, прикольная ошибка
|
| Автор: LSD 25.9.2006, 16:09 |
| Думаю тут лучше использовать ReentrantReadWriteLock. Создаешь объект ReentrantReadWriteLock, затем читающий поток делает lock.readLock().lock() (если сейчас коллекция заблокированна на запись, то он просто встанет), работаешь с коллекцией, затем после того как читающий поток отработал делаешь lock.readLock().unlock(). Когда пишущему потоку надо будет изменять коллекцию, делаешь lock.writeLock().lock() (он тоже встанет, если сейчас кто-то читает из коллекции), когда пишущий поток закончит менять коллекцию: lock.writeLock().unlock(). Пишущий поток получает эксклюзивную блокировку на объект, читающие потоки не эксклюзивную. Плюс можно устанавливать таймауты на ожидание блокировки. |
| Автор: polakwilno 26.9.2006, 22:42 |
| Ну вот, уже 2 дня все работает нормально (раньше регулярно раз в день зависал Всем спасибо, в который раз выручаете ;) Ай да, помог обычный Synchronized(vector). Поставил его на цикл, который ищет вектора на удаление... |
| Автор: COVD 26.9.2006, 23:08 |
| Ну вот, люди в Sun стараются, придумывают всякие lock.readLock().unlock().lock().unlock().., а вы обычный synchronize() применяете |
| Автор: polakwilno 29.9.2006, 00:08 | ||
|