Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Threads & vectors 
V
    Опции темы
polakwilno
Дата 25.9.2006, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Добрый день,

Народ, помогите советом, как избавится от такой проблемы:

Код

for(int i=0; i<v.size(); i++)    // v - вектор
    doSomeStuff(v.get(i));


Проблема возникает, когда size() вернет, скажем, 5, а перед вызовом какойто thread удалит один из елементов. Как защитить вектор ТОЛЬКО ОТ УДАЛЕНИЯ - возможность добавления и редактирования должна остатся...

Это сообщение отредактировал(а) polakwilno - 25.9.2006, 10:56
PM MAIL   Вверх
powerOn
Дата 25.9.2006, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Код

synchronized (v) {
for(int i=0; i<v.size(); i++)    // v - вектор
    doSomeStuff(v.get(i));
}




--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
polakwilno
Дата 25.9.2006, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Цитата(powerOn @ 25.9.2006,  11:13)
Код

synchronized (v) {
for(int i=0; i<v.size(); i++)    // v - вектор
    doSomeStuff(v.get(i));
}

synchronized() вроде разрешает в тотже момент времени использовать переменную только одному процессу, то есть пока будет выполнятся for цикл я не смогу просто изменить вектор или добавить новый элемент... Или я неправ?
PM MAIL   Вверх
batigoal
Дата 25.9.2006, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 24
Всего: 151



В Java 5 есть пакет concurrent, который позволяет более гибко работать с многопоточностью. В частности, там есть класс ReadWriteLock, который позволяет отдельно блокировать чтение и запись. Но проблемы с апдейтом это не решает.

Добавлено @ 12:56 
На самом деле, я не понял, почему мы синхронизируем цикл for(), а не кусок кода с удалением.


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
polakwilno
Дата 25.9.2006, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Цитата(batigoal @ 25.9.2006,  12:54)
Добавлено @ 12:56 
На самом деле, я не понял, почему мы синхронизируем цикл for(), а не кусок кода с удалением.

Так тоже врятли поможет... Получит он размер вектора 5, а потом код с удалением заблокирует вектор, удалит 1 элемент и освободит веткор. А метод get опять-же будет пытатся взять несуществующий элемент... 

Попробую наверно про concurent  почитать, может чего полезного найду...
PM MAIL   Вверх
LSD
Дата 25.9.2006, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(polakwilno @  25.9.2006,  14:05 Найти цитируемый пост)
Так тоже врятли поможет... Получит он размер вектора 5, а потом код с удалением заблокирует вектор, удалит 1 элемент и освободит веткор. А метод get опять-же будет пытатся взять несуществующий элемент... 

Это поможет. Все методы меняющие 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.
PM MAIL WWW   Вверх
polakwilno
Дата 25.9.2006, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Цитата(LSD @ 25.9.2006,  13:39)
Это поможет.

Возможно сама идея правильная, но мне кажется появится много багов изза того что ктото чегото не сможет записать пока вектор будет заблокирован... Но конечно надеюсь, что все будет работать нормально smile

Потестирую сервак 1-2 дня потом напишу что получилось ;)
PM MAIL   Вверх
LSD
Дата 25.9.2006, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(polakwilno @  25.9.2006,  15:25 Найти цитируемый пост)
мне кажется появится много багов изза того что ктото чегото не сможет записать пока вектор будет заблокирован...

Ну вообщем, да, тут будет почти полная блокировка.

Если тебе надо блокировать тольку удаление, то придется писать свою коллекцию.


--------------------
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.
PM MAIL WWW   Вверх
powerOn
Дата 25.9.2006, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата(batigoal @  25.9.2006,  13:54 Найти цитируемый пост)
На самом деле, я не понял, почему мы синхронизируем цикл for(), а не кусок кода с удалением. 


мы синхронизируем не сколько цикл for, сколько участок кода работающий с объектом вектора. Вот и весь смысл.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
polakwilno
Дата 25.9.2006, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Цитата(LSD @ 25.9.2006,  14:28)
Если тебе надо блокировать тольку удаление, то придется писать свою коллекцию.

LSD, удаление как таковое я заблокировал... Сделал специяльные методы get() и setFree(), которые увеличивают/уменьшают счетчик процесов, которые в данный момент используют вектор. А thread который удаляет ненужные элементы вектора, смотрит равен-ли счетчик 0, если да то удаляет, иначе - пропускает. 

Пробовал сделать похожее с функцией size() - увеличить счетчик а потом уменьшить, но тут много нюансов - делаешь чтоб работало в 1 месте - не работает в другом... В принципе, если synchronized() не поможет придется както делать счетчик на size()... Придется очень много переделать, но зато реально добится нужного результата. Просто думал попробую решить стандартными средствами, без всяких наворотов... smile


Хе хе, прикольная ошибка
Цитата

ERROR: Cannot find database vingrad_pforum Возникла SQL ошибка при обращении к БД форума.
PS: Э...э бывает smile

PM MAIL   Вверх
LSD
Дата 25.9.2006, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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.
PM MAIL WWW   Вверх
polakwilno
Дата 26.9.2006, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Ну вот, уже 2 дня все работает нормально (раньше регулярно раз в день зависалsmile). Думаю, проблема решена...

Всем спасибо, в который раз выручаете ;)

Ай да, помог обычный Synchronized(vector). Поставил его на цикл, который ищет вектора на удаление...

Это сообщение отредактировал(а) polakwilno - 26.9.2006, 22:43
PM MAIL   Вверх
COVD
Дата 26.9.2006, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Ну вот, люди в Sun стараются, придумывают всякие lock.readLock().unlock().lock().unlock().., а вы обычный synchronize() применяете  smile 
PM MAIL   Вверх
polakwilno
Дата 29.9.2006, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 14.8.2006

Репутация: нет
Всего: нет



Цитата(COVD @ 26.9.2006,  23:08)
Ну вот, люди в Sun стараются, придумывают всякие lock.readLock().unlock().lock().unlock().., а вы обычный synchronize() применяете  smile

 smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0935 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.