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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> java.util.concurrent. Выбор коллекции, лок только на время модификации 
V
    Опции темы
chief39
Дата 26.10.2006, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


карманная тигра
***


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

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



Всем привет...

Вроде почитал предыдущие опусы, джавадоку листнул...

Но как-то недовъехал....

Придётся ли дописывать под себя...

Суть вопроса:

Необходимо держать коллекцию в памяти, доступной для паралелльных обращений множества READ'ов
Но, иногда, когда происходит модификация(а именно - замена одного из элементов...) - READ'ы этой записи необходимо запрещать.

Причём взаимные локи ридов надо исключить.


java.util.concurrent.CopyOnWriteArrayList подойдёт?
Я так понял, при обращении рида, он будет считывать и, если начнётся write - дочитает со своей копии.
И только при следующем обновлении считает новое значение.


Ещё есть нюанс - рид проверяет валидность записи - если всё плохо - инициализирует write.
Если придут много ридов, увидят что запись плоха и паралелльно инициализируют write... В общем, этого надо избежать smile

Без флажков не обойтись? или... ?

Добавлено @ 12:56 
Да... ещё... 

Чтоб исключить 
если проверку
Цитата(chief39 @  26.10.2006,  12:53 Найти цитируемый пост)
Если придут много ридов, увидят что запись плоха и паралелльно инициализируют write... 

на невалидность записи синхронизировать в один блок с врайтом - тогда множества паралелльных write'ов можно избежать, имхо...
Но! Тогда в нормальном рабочем режиме READ'ы будут локать друг друга на этой проверке smile



--------------------
Люди - это свечи. Они либо горят, либо их - в жопу!(с)

PM MAIL   Вверх
powerOn
Дата 26.10.2006, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


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

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



Цитата(chief39 @  26.10.2006,  13:53 Найти цитируемый пост)
в нормальном рабочем режиме READ'ы будут локать друг друга

Зачем ридерам блокировать друг друга если они ничего не меняют, а просто читают информацию?

Нельзя ли просто во время изменения коллекции использовать synchronized(коллекция)?




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

PM MAIL   Вверх
chief39
Дата 26.10.2006, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


карманная тигра
***


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

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



Цитата(powerOn @  26.10.2006,  14:53 Найти цитируемый пост)
Зачем ридерам блокировать друг друга если они ничего не меняют, а просто читают информацию?

Нельзя ли просто во время изменения коллекции использовать synchronized(коллекция)?



Стоп... Ридерам тоже синхронизированно считывать с врайтером.
Если во время изменения поставить синхро, а в это же время риды без синхро будут читать как захотят... и пофиг им будет, что кто-то изменяет... Или я промахнулся?



--------------------
Люди - это свечи. Они либо горят, либо их - в жопу!(с)

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


Эксперт
***


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

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



У вас модификация - замена элемента, т.е.  операция присвоения. Если считать эту операцию атомарной, то никакой синхронизации не надо, потому что невозможна ситуация, когда райтер наполовину вписал ссылку на новый обьект и остановился, а ридер пытается по этой недописанной ссылке получить доступ к обьекту. 
PM MAIL   Вверх
powerOn
Дата 26.10.2006, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


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

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



Цитата(chief39 @  26.10.2006,  15:57 Найти цитируемый пост)
Если во время изменения поставить синхро, а в это же время риды без синхро будут читать как захотят... и пофиг им будет, что кто-то изменяет... Или я промахнулся?


 я попробовал код в котором в synchronized() ставится код writer-a, а код reader-a не использует synchronized() - не работает. smile сорри.

Я думаю надо код и writer-a и reader-a ставить в synchronized(), но не весь. у reader-a только саму операцию чтения и все. (только коллекция.дайЭлемент()) (да и у writer-a впринципе можно только операцию помещения элемента в коллекцию поместить в synchronized()) Хоть и будет блокировка, но думаю вполне приемлемая.   smile 



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

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


карманная тигра
***


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

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



Цитата(COVD @  26.10.2006,  15:20 Найти цитируемый пост)
У вас модификация - замена элемента, т.е.  операция присвоения. Если считать эту операцию атомарной, то никакой синхронизации не надо, потому что невозможна ситуация, когда райтер наполовину вписал ссылку на новый обьект и остановился, а ридер пытается по этой недописанной ссылке получить доступ к обьекту.  

Проскакивала эта мысль...
Действительно... smile

Ещё один нюанс....

Если несколько тредов находят что запись устарела и запускают write:

Пока первый подтягивает данные... второй начинает подтягивать...
Первый - обновляет, начинает считывать, второй начинает обновлять...
А если их с несколько десятков - они десятки раз могут обновить одно и то же...

Неплохо бы сделать так, чтоб только первый подтягивал... 
но тогда все остальные, "пришедшие после него", должны вместо собственного обновления, ждать того первого... тут бы не помешало их как-то остановить...
Выходит, нужен флаг "обновляю", остальные натыкаются и ждут обновления...

Как бы попроще так?



--------------------
Люди - это свечи. Они либо горят, либо их - в жопу!(с)

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


Leprechaun Software Developer
****


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

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



Т.е. как я понял тебе надо нечто вроде select for update, да?


--------------------
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   Вверх
chief39
Дата 26.10.2006, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


карманная тигра
***


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

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



Цитата(powerOn @  26.10.2006,  15:37 Найти цитируемый пост)
у reader-a только саму операцию чтения и все. 

Как раз этого хочу избежать...
Можно всё синхронизировать - ридер залез, заблокировал, проверил, если надо, обновил, вышел.
Последующие даже не узнают, что он обновлял.
Но нормальный рабочий режим - тысячи ридов без врайта... и вот как раз хочу избежать ЛЮБЫХ блокировок без райта :-/

Стоп!
А кто что может сказать насчёт фичи java.util.concurrent:

Цитата(Maksym @  10.8.2006,  14:04 Найти цитируемый пост)
CountDownLatch — реализует синхронизационную модель «щеколды» — создается щеколда (с натуральным числом в качестве параметра-счетчика), которая постепенно вынимается с выполнение каких-то операций (как только такая операция выпонена, вызывается метод void countDown(), уменьшающий счетчик). Потоки, которые должны подождать конца выполнения данной цепочки операций, вызывают метод await() и блокируются. Как только щеколда будет вынута (счетчик упадет до нуля), все ожидающие потоки разблокируются и продолжают выполнение.


Кто-то использовал? Если все риды работают нормально, но если приходит злой райт, закрывает всё на щеколду и риды просто ждут когда он сделает своё чёрное дело.... а?


--------------------
Люди - это свечи. Они либо горят, либо их - в жопу!(с)

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


Опытный
**


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

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



Обычно используются rwlock в таком случае. ридеры ставят readlock, их можно сколько угодно одновременно ставить на один rwlock. То есть сколько угодно тридов могут одновременно читать твою коллецию.


 А writer - должен ставить writelock он может быть только один и будет ждать пока все readlock-и освободятся




--------------------
 Бонифаций.
 
PM MAIL ICQ Skype GTalk Jabber YIM   Вверх
chief39
Дата 26.10.2006, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


карманная тигра
***


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

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



Цитата(LSD @  26.10.2006,  15:47 Найти цитируемый пост)
Т.е. как я понял тебе надо нечто вроде select for update, да? 


Нет. Нужен кэш smile

Мы вытягиваем список данных.
Каждый трэд будет в момент времени Х вытягивать из хэшмапы только одну запись по ключу
Но если он вытягивает её... видит, что она устарела... он начинает просит новую запись из некого датасорса(сешн-бина etc)
В момент, когда он обновляет - никто не читает - ждут пока он для всех постарается - подтянет новое...
обновляет - означает, что он вытягивает свежие данные.
Изменений, инициированных в клиенте кэша не будет по определению - просто нужна свежая инфа.

Добавлено @ 15:56 
Цитата(Бонифаций @  26.10.2006,  15:50 Найти цитируемый пост)
Обычно используются rwlock в таком случае. ридеры ставят readlock, их можно сколько угодно одновременно ставить на один rwlock. То есть сколько угодно тридов могут одновременно читать твою коллецию.

Зачем их тогда вообще ставить? Что они будут блокировать?

Цитата(Бонифаций @  26.10.2006,  15:50 Найти цитируемый пост)
А writer - должен ставить writelock он может быть только один и будет ждать пока все readlock-и освободятся

Ага.. понял... чтоб не начали обновлять, пока все не дочитают...
А будут ли потом риды терпеливо ждать снятия writelock ?



--------------------
Люди - это свечи. Они либо горят, либо их - в жопу!(с)

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


Опытный
**


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

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





--------------------
 Бонифаций.
 
PM MAIL ICQ Skype GTalk Jabber YIM   Вверх
LSD
Дата 26.10.2006, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


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

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



Цитата(chief39 @  26.10.2006,  16:48 Найти цитируемый пост)
Кто-то использовал? Если все риды работают нормально, но если приходит злой райт, закрывает всё на щеколду и риды просто ждут когда он сделает своё чёрное дело.... а?

Зачем тебе щеколда? Тебе достаточно простого lock.tryLock(). Проблема только в том, что тебе придется создать еще один список с Lock-ами, или HashMap. А это может потребовать лишних расходов памяти и синхронизации (для HashMap).


--------------------
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   Вверх
COVD
Дата 26.10.2006, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



А зачем давать право на апдейт ридерам? Ридер должен рид. А следить за свежестью осетрины назначить толкового майора - отдельный поток. Может все упростится?
PM MAIL   Вверх
LSD
Дата 26.10.2006, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


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

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



Цитата(COVD @  26.10.2006,  17:06 Найти цитируемый пост)
А зачем давать право на апдейт ридерам? Ридер должен рид. А следить за свежестью осетрины назначить толкового майора - отдельный поток. Может все упростится?

Если майор не успеет обновить данные, то читатели скушают несвежую осетрину. А если никто не будет обедать двое суток, то майор понапрасну будет вылавливать и вылавливать новую осетрину.


--------------------
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   Вверх
chief39
Дата 26.10.2006, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


карманная тигра
***


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

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



Что-то вроде такого справится?
Код

    /**
     * собсссно то, что я хочу хранить в кэше
     */
    public class Record{
        public    int x;
        public int y;
        public Record(int ex, int ey){
            x = ex;
            y = ey;
        }
    }

    /**
     * То же самое, но обёрнутое классом, который в себе держит лок для этого рекорда
     */
    private class RecordWithLock{

        /**
         * Лок для данного рекорда
         */
        public ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
        
        /**
         * Сама Запись
         */        
        public Record record;
        RecordWithLock(Record erecord){
            record = erecord;
        }

        /**
         * Тот метод, который будет изменять запись(обновлять)
         * 
         */
        public void refreshRecord(){
            /**
             * Код тут будет совсем другой
             * обновление. всё это с райтлоком 
             */            
        }

        /**
         * Это будет нашенский ридер... 
         * @return Необходимый нам элемент
         */
        public Record getRecord(){
            /** проверка валидности и , при необходимости, обновление. всё это с ридлоком */
            return record;
        }

    }


То есть синхронизировать будем на уровне записи, лок хранится тоже в записи, хэшмап о таких ужастях даже не знает...
При обновлении просто подкидывается новый(другой) рекорд в РекордВизМэп.


Но вот.... если приходит поток - читает... а такого рекорда у нас ещё нету... - начинает подтягивать...
И тут второй начинает то же самое делать...

Выходит что в мапу будут пытаться дописать одновременно...
Как тогда добавление лучше синхронизировать и сделать его единичным?



--------------------
Люди - это свечи. Они либо горят, либо их - в жопу!(с)

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

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

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


 




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


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

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