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

То есть чтобы одновременные вызовы 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
Синхронизация по String
    #37735122
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А чего вы хотите добиться? Я имею ввиду, что возможно вы идете окружным путем, а решение проще и элегантней. Что касается того кода что вы привели, выполнить какой-то код, основываясь на параметре, то да, можно завести коллекцию, не обязательно ConcurrentHashMap, в цикле делать CAS, ожидая пока ячейка освободиться, и когда освободиться выполнить свой код, Только опять же иногда CAS намного хуже чем обычный Lock, если contention большой. Можете описать задачу конкретней?
...
Рейтинг: 0 / 0
Синхронизация по String
    #37735123
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я так полагаю что это какое-то подобие кэша, который поддерживает работу с несколькими потоками? Тогда вам определенно надо скачать Java Concurrency in practice, там целая глава посвящена кэшам, и есть там хороший пример с Future и Computable
...
Рейтинг: 0 / 0
Синхронизация по String
    #37735188
shainsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл ник,

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

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

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

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

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

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

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

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

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

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

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

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


и синхронизироваться по нему
...
Рейтинг: 0 / 0
Синхронизация по String
    #37735488
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Синхронизация по String
    #37735545
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Синхронизация по String
    #37735769
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никЗачем эта мутотень если уже 5 лет есть Lock?

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

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


Как на счет spurious wakeup?
...
Рейтинг: 0 / 0
Синхронизация по String
    #37735791
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OOsalivanLock есть, и как вы его собираетесь к этой задаче применить, где ваш код?
Или это самоутверждение?
Всё тоже самое, только вместо Object - Lock и synchronized не нужен.
Lock рекомедуют к использованию вместо wait/notify. Но мне любопытно на счет производительности. Lock устроен горзда сложнее с кучей вызовов методов.
...
Рейтинг: 0 / 0
Синхронизация по String
    #37736035
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Синхронизация по String
    #37736077
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OOsalivanА где вы видите проблему с spurious wakeup?
while (map.put(s, true) == true) - как раз для этого и написано
Ааа, там предыдущее значение выталкивается. Я подумал что флаг. А NPE не будет ли при анбоксинге null? В любом случае при первом заходе там всегда не true. Рантайм в цикл вообще не попадёт.
...
Рейтинг: 0 / 0
Синхронизация по String
    #37736083
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczАаа, там предыдущее значение выталкивается. Я подумал что флаг. А NPE не будет ли при анбоксинге null? В любом случае при первом заходе там всегда не true. Рантайм в цикл вообще не попадёт.
Ой, блин что-то я гоню. Это же только для того случая если строка есть.
А ещё вопрос, все ведь строки на одном локе висят. Тогда если две разных строки в 2х потоках уже существуею, они ещё и с друг другом будут бодаться за lock?
...
Рейтинг: 0 / 0
Синхронизация по String
    #37736090
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И ещё вопрос к коду. Как отработает re-entrancy, если метод вызовется для той же строки, но в том же потоке?
...
Рейтинг: 0 / 0
25 сообщений из 36, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронизация по String
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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