![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
polakwilno |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
Добрый день,
Народ, помогите советом, как избавится от такой проблемы:
Проблема возникает, когда size() вернет, скажем, 5, а перед вызовом какойто thread удалит один из елементов. Как защитить вектор ТОЛЬКО ОТ УДАЛЕНИЯ - возможность добавления и редактирования должна остатся... Это сообщение отредактировал(а) polakwilno - 25.9.2006, 10:56 |
|||
|
||||
powerOn |
|
|||
![]() software saboteur ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4367 Регистрация: 7.10.2005 Репутация: 47 Всего: 159 |
|
|||
|
||||
polakwilno |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
synchronized() вроде разрешает в тотже момент времени использовать переменную только одному процессу, то есть пока будет выполнятся for цикл я не смогу просто изменить вектор или добавить новый элемент... Или я неправ? |
||||
|
|||||
batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 24 Всего: 151 |
В Java 5 есть пакет concurrent, который позволяет более гибко работать с многопоточностью. В частности, там есть класс ReadWriteLock, который позволяет отдельно блокировать чтение и запись. Но проблемы с апдейтом это не решает.
Добавлено @ 12:56 На самом деле, я не понял, почему мы синхронизируем цикл for(), а не кусок кода с удалением. -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
polakwilno |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
Так тоже врятли поможет... Получит он размер вектора 5, а потом код с удалением заблокирует вектор, удалит 1 элемент и освободит веткор. А метод get опять-же будет пытатся взять несуществующий элемент... Попробую наверно про concurent почитать, может чего полезного найду... |
|||
|
||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Это поможет. Все методы меняющие java.util.Vector просто объявлены synchronized, поэтому захватив блокировку на этот Vector мы предотвратим все вызовы подобных методов. В том числе и insertElementAt() и set() и даже indexOf(). В принципе есть java.util.concurrent.CopyOnWriteArrayList - когда список менятся, создается новая копия массива используемого для хранения элементов. Таким образом итератор, всегда работает со старым вариантом списка, но это делает вставленные и измененные элементы невидимыми для итератора. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
polakwilno |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
Возможно сама идея правильная, но мне кажется появится много багов изза того что ктото чегото не сможет записать пока вектор будет заблокирован... Но конечно надеюсь, что все будет работать нормально ![]() Потестирую сервак 1-2 дня потом напишу что получилось ;) |
|||
|
||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Ну вообщем, да, тут будет почти полная блокировка. Если тебе надо блокировать тольку удаление, то придется писать свою коллекцию. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
powerOn |
|
|||
![]() software saboteur ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4367 Регистрация: 7.10.2005 Репутация: 47 Всего: 159 |
||||
|
||||
polakwilno |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
LSD, удаление как таковое я заблокировал... Сделал специяльные методы get() и setFree(), которые увеличивают/уменьшают счетчик процесов, которые в данный момент используют вектор. А thread который удаляет ненужные элементы вектора, смотрит равен-ли счетчик 0, если да то удаляет, иначе - пропускает. Пробовал сделать похожее с функцией size() - увеличить счетчик а потом уменьшить, но тут много нюансов - делаешь чтоб работало в 1 месте - не работает в другом... В принципе, если synchronized() не поможет придется както делать счетчик на size()... Придется очень много переделать, но зато реально добится нужного результата. Просто думал попробую решить стандартными средствами, без всяких наворотов... ![]() Хе хе, прикольная ошибка
|
||||
|
|||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Думаю тут лучше использовать ReentrantReadWriteLock.
Создаешь объект ReentrantReadWriteLock, затем читающий поток делает lock.readLock().lock() (если сейчас коллекция заблокированна на запись, то он просто встанет), работаешь с коллекцией, затем после того как читающий поток отработал делаешь lock.readLock().unlock(). Когда пишущему потоку надо будет изменять коллекцию, делаешь lock.writeLock().lock() (он тоже встанет, если сейчас кто-то читает из коллекции), когда пишущий поток закончит менять коллекцию: lock.writeLock().unlock(). Пишущий поток получает эксклюзивную блокировку на объект, читающие потоки не эксклюзивную. Плюс можно устанавливать таймауты на ожидание блокировки. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
polakwilno |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
Ну вот, уже 2 дня все работает нормально (раньше регулярно раз в день зависал
![]() Всем спасибо, в который раз выручаете ;) Ай да, помог обычный Synchronized(vector). Поставил его на цикл, который ищет вектора на удаление... Это сообщение отредактировал(а) polakwilno - 26.9.2006, 22:43 |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Ну вот, люди в Sun стараются, придумывают всякие lock.readLock().unlock().lock().unlock().., а вы обычный synchronize() применяете
![]() |
|||
|
||||
polakwilno |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 14.8.2006 Репутация: нет Всего: нет |
![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |