Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронизация по String / 25 сообщений из 36, страница 1 из 2
02.04.2012, 18:13:18
    #37735089
shainsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Кто подскажет шаблон для синхронизации кода не по экземпляру объекта, а по строке?

То есть чтобы одновременные вызовы someMethod("a") и someMethod("b") выполнялись параллельно, а вызовы someMethod("a") и someMethod("a") - по очереди.

Я придумал такой код, но есть подозрения в том, что он неоптимален:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
 

    static ConcurrentMap<String, String> workWith = new ConcurrentHashMap<String, String>();
         ...
        
    void someMethod(String s) {

        String current = workWith.putIfAbsent(s, s);
        if (current == null)
            current = s;
        synchronized (current) {

         // синхронизированный код ...

            workWith.remove(s);
        }
    }
...
Рейтинг: 0 / 0
02.04.2012, 18:38:15
    #37735122
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
А чего вы хотите добиться? Я имею ввиду, что возможно вы идете окружным путем, а решение проще и элегантней. Что касается того кода что вы привели, выполнить какой-то код, основываясь на параметре, то да, можно завести коллекцию, не обязательно ConcurrentHashMap, в цикле делать CAS, ожидая пока ячейка освободиться, и когда освободиться выполнить свой код, Только опять же иногда CAS намного хуже чем обычный Lock, если contention большой. Можете описать задачу конкретней?
...
Рейтинг: 0 / 0
02.04.2012, 18:40:54
    #37735123
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Я так полагаю что это какое-то подобие кэша, который поддерживает работу с несколькими потоками? Тогда вам определенно надо скачать Java Concurrency in practice, там целая глава посвящена кэшам, и есть там хороший пример с Future и Computable
...
Рейтинг: 0 / 0
02.04.2012, 19:12:09
    #37735188
shainsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
забыл ник,

Это не подобие хэша. Я пишу обработчик вызовов удаленного метода.
У меня есть некая сущность, скажем, клиентский счет. Он идентифицируется строковым UUID'ом. Таких сущностей на сервере может быть несколько тысяч.
Мне надо делать синхронизацию на основе UUID'а.
Чтобы два клиента одновременно не редактировали одновременно эту сущность.
...
Рейтинг: 0 / 0
02.04.2012, 19:26:39
    #37735218
Йуный джавистЪ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Во-первых, я не очень понимаю, зачем нужна проверка на null.
Во-вторых, что из себя представляет эта сущность? Если это объект внутри JVM, то синхронизируйтесь прям на нем. Если это строчка в базе данных, то захватывайте лок на этой строчке в БД (это происходит автоматически при update или delete).
...
Рейтинг: 0 / 0
02.04.2012, 19:30:52
    #37735224
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
авторВо-вторых, что из себя представляет эта сущность? Если это объект внутри JVM, то синхронизируйтесь прям на нем. Если это строчка в базе данных, то захватывайте лок на этой строчке в БД (это происходит автоматически при update или delete).

Я тоже так думаю, может топикстартер чего-то недоговаривает?
...
Рейтинг: 0 / 0
02.04.2012, 19:32:58
    #37735225
shainsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Йуный джавистЪВо-первых, я не очень понимаю, зачем нужна проверка на null.
Почитайте джавадок метода ConcurrentMap.putIfAbsent()

Йуный джавистЪВо-вторых, что из себя представляет эта сущность? Если это объект внутри JVM, то синхронизируйтесь прям на нем.
Спасибо, кэп! :)

Йуный джавистЪЕсли это строчка в базе данных, то захватывайте лок на этой строчке в БД (это происходит автоматически при update или delete).
Это сущность в нереляционном дата-бэкенде.
...
Рейтинг: 0 / 0
02.04.2012, 19:41:35
    #37735241
shainsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
забыл никавторВо-вторых, что из себя представляет эта сущность? Если это объект внутри JVM, то синхронизируйтесь прям на нем. Если это строчка в базе данных, то захватывайте лок на этой строчке в БД (это происходит автоматически при update или delete).

Я тоже так думаю, может топикстартер чего-то недоговаривает?

Это сущность в самописном нереляционном дата-бэкенде. У меня нет уверенности в корректной поддержке конкурентной модификации сущностей внутри этого бэкенда.
...
Рейтинг: 0 / 0
02.04.2012, 19:41:49
    #37735242
Йуный джавистЪ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Почитайте джавадок метода ConcurrentMap.putIfAbsent()
Теперь понял.
Это сущность в нереляционном дата-бэкенде.

Можно поинтересоваться, в каком? Даже в файловой системе есть локи.
...
Рейтинг: 0 / 0
02.04.2012, 19:50:14
    #37735253
shainsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Это сущность в нереляционном дата-бэкенде.

Можно поинтересоваться, в каком? Даже в файловой системе есть локи.

Кэширующее реплицируемое хранилище игровых объектов. По сути легаси-система, написана на С++. Используется в многопользовательской игре. Количество типов объектов ограничено и заранее описано. Не знаю, что ещё рассказать Вам о нем.
...
Рейтинг: 0 / 0
02.04.2012, 20:02:49
    #37735265
schwa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
shainsky,

Кладите вместо строки либо просто новый созданный объект, либо какую-нибудь из реализаций java.util.concurrent.locks.Lock
...
Рейтинг: 0 / 0
02.04.2012, 20:11:14
    #37735274
shainsky
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
schwashainsky,

Кладите вместо строки либо просто новый созданный объект, либо какую-нибудь из реализаций java.util.concurrent.locks.Lock

Вместо current = s написать current = new Object() ?
А в чем здесь оптимизация? В моем случае кладется уже существующий объект, а в Вашем - новый, который надо создавать и хранить.
Или я неправильно понял?
...
Рейтинг: 0 / 0
02.04.2012, 20:28:34
    #37735295
schwa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
Вы не то оптимизируете - вам нужно оптимизировать время пребывания в блоке synchronized и количество тех, кто борется за это монитор.
...
Рейтинг: 0 / 0
02.04.2012, 20:30:18
    #37735298
schwa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
За этоТ монитор, который создается, или достается из мапа, а вы боритесь с GC вместо этого.
...
Рейтинг: 0 / 0
02.04.2012, 23:40:58
    #37735480
grasoff.net
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
intern() но это не очень здорово, поэтому проще создать
Код: java
1.
2.
3.
4.
5.
6.
class StringMutex {
  private String value;
  Mutex(String value) {this.value = value;}
  hashcode() {...}
  equals() {...}
}


и синхронизироваться по нему
...
Рейтинг: 0 / 0
03.04.2012, 00:02:28
    #37735488
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
shainsky,

Еще вариант
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
private final ConcurrentMap<String, Boolean> map = new ConcurrentHashMap<String, Boolean>();
	private final Object lock = new Object();
	
	void someMethod(String s) throws InterruptedException {	
		while (map.put(s, true) == true) {
			synchronized (lock) {
				lock.wait();
			}		
		}
		//синхронизированный код	
		map.put(s, false);
		lock.notifyAll();
	}
...
Рейтинг: 0 / 0
03.04.2012, 02:15:51
    #37735545
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
OOsalivanshainsky,

Еще вариант
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
private final ConcurrentMap<String, Boolean> map = new ConcurrentHashMap<String, Boolean>();
	private final Object lock = new Object();
	
	void someMethod(String s) throws InterruptedException {	
		while (map.put(s, true) == true) {
			synchronized (lock) {
				lock.wait();
			}		
		}
		//синхронизированный код	
		map.put(s, false);
		lock.notifyAll();
	}


Зачем эта мутотень если уже 5 лет есть Lock?
...
Рейтинг: 0 / 0
03.04.2012, 10:23:27
    #37735769
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
забыл никЗачем эта мутотень если уже 5 лет есть Lock?

Lock есть, и как вы его собираетесь к этой задаче применить, где ваш код?
Или это самоутверждение?
...
Рейтинг: 0 / 0
03.04.2012, 10:29:14
    #37735781
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
schwaВы не то оптимизируете - вам нужно оптимизировать время пребывания в блоке synchronized и количество тех, кто борется за это монитор.
+1
...
Рейтинг: 0 / 0
03.04.2012, 10:29:47
    #37735783
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
OOsalivanshainsky,

Еще вариант
Код: java
1.
2.
3.
4.
5.
		while (map.put(s, true) == true) {
			synchronized (lock) {
				lock.wait();
			}		
		}


Как на счет spurious wakeup?
...
Рейтинг: 0 / 0
03.04.2012, 10:33:17
    #37735791
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
OOsalivanLock есть, и как вы его собираетесь к этой задаче применить, где ваш код?
Или это самоутверждение?
Всё тоже самое, только вместо Object - Lock и synchronized не нужен.
Lock рекомедуют к использованию вместо wait/notify. Но мне любопытно на счет производительности. Lock устроен горзда сложнее с кучей вызовов методов.
...
Рейтинг: 0 / 0
03.04.2012, 12:13:19
    #37736035
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
BlazkowiczOOsalivanshainsky,

Еще вариант
Код: java
1.
2.
3.
4.
5.
		while (map.put(s, true) == true) {
			synchronized (lock) {
				lock.wait();
			}		
		}


Как на счет spurious wakeup?

А где вы видите проблему с spurious wakeup?

while (map.put(s, true) == true) - как раз для этого и написано
...
Рейтинг: 0 / 0
03.04.2012, 12:24:20
    #37736077
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
OOsalivanА где вы видите проблему с spurious wakeup?
while (map.put(s, true) == true) - как раз для этого и написано
Ааа, там предыдущее значение выталкивается. Я подумал что флаг. А NPE не будет ли при анбоксинге null? В любом случае при первом заходе там всегда не true. Рантайм в цикл вообще не попадёт.
...
Рейтинг: 0 / 0
03.04.2012, 12:26:08
    #37736083
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
BlazkowiczАаа, там предыдущее значение выталкивается. Я подумал что флаг. А NPE не будет ли при анбоксинге null? В любом случае при первом заходе там всегда не true. Рантайм в цикл вообще не попадёт.
Ой, блин что-то я гоню. Это же только для того случая если строка есть.
А ещё вопрос, все ведь строки на одном локе висят. Тогда если две разных строки в 2х потоках уже существуею, они ещё и с друг другом будут бодаться за lock?
...
Рейтинг: 0 / 0
03.04.2012, 12:28:27
    #37736090
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Синхронизация по String
И ещё вопрос к коду. Как отработает re-entrancy, если метод вызовется для той же строки, но в том же потоке?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронизация по String / 25 сообщений из 36, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]