powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Как использовать ReentrantLock вместо Synchronized в данном случае?
23 сообщений из 23, страница 1 из 1
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504742
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть класс сервис и его объект в единственном экземпляре, в котором есть метод который работает в много поточной среде, в нем имеется такой код:
Код: java
1.
2.
3.
4.
5.
6.
7.
		synchronized (q) {
			if (q.getVotes() == null) {
				q.setVotes(1);
			} else {
				q.setVotes(q.getVotes() + 1);
			}
		}


q - объект другого класса, их может быть множество

Как можно подобное реализовать с помощью ReentrantLock или может есть какой-то другой инструмент из concurrent? Была мысль класть Локи в ConcurrentHashMap, где ключе - объекты q, а значения - локи. Но есть проблема, объекты q - мы не можем хранить в мапе вечно, надо их от туда удалять, но нужно будет выполнять на них .unlock() и .remove() - это две операции, в итоге другой поток в промежуток между ними может начать работать со своим, вторым, локом.
Можно было бы сделать поле AromicInteger но не хочется.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504768
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindКак можно подобное реализовать с помощью ReentrantLock или может есть какой-то другой инструмент из concurrent?

https://www.google.com/search?q=ReentrantLock
По любой ссылке есть пример. Что вызывает сложности?

MaxNevermindМожно было бы сделать поле AromicInteger но не хочется.
Это ещё почему?
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504818
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Blazkowicz]MaxNevermindКак можно подобное реализовать с помощью ReentrantLock или может есть какой-то другой инструмент из concurrent?

https://www.google.com/search?q=ReentrantLock
По любой ссылке есть пример. Что вызывает сложности?

Везде - простые примеры блокировки самого объекта в котором выполняется .lock(), у меня не этот случай.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504856
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermind
Код: java
1.
2.
3.
4.
5.
6.
7.
		synchronized (q) {
			if (q.getVotes() == null) {
				q.setVotes(1);
			} else {
				q.setVotes(q.getVotes() + 1);
			}
		}



А ещё ваш код это прямое нарушение инкапсуляции. Его целиком и полностью можно унести внутрь класса переменной Q и тогда проблема с хранением лока уйдёт.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504860
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindВезде - простые примеры блокировки самого объекта в котором выполняется .lock(), у меня не этот случай.
synchronized это и есть .lock() не вижу разницы. Теперь разобрался что вам сам Lock хранить негде.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504863
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Блокировка ради инкремента... Чем атомик-то не устроил, самое место ему тут
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38504870
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraБлокировка ради инкремента... Чем атомик-то не устроил, самое место ему тут
Да, есть такие программисты, которым лишь бы всё усложнить. ConcurrentHashMap ещё сверху навернуть чтобы Lock хранить...
Хотя весь такой код выкидывается и заменяется на 2 строчки правильныого кода в правильном месте.
Было у меня как-то, дал коллеге задачу, получили в результате метод на полтора экрана в высоту. Переписал потом этот метод в 4 строки кода.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505043
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraБлокировка ради инкремента... Чем атомик-то не устроил, самое место ему тут
Но есть же случаи в которых q.getVotes() будет вызываться и без последующего приращения? Я думал логично синхронизировать только ту часть где возможны проблемы, а не делать поле Atomic для всех объектов-юзеров.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505055
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindНо есть же случаи в которых q.getVotes() будет вызываться и без последующего приращения?
И что? По-вашему атомики этого не позволяют?

MaxNevermindЯ думал логично синхронизировать только ту часть где возможны проблемы, а не делать поле Atomic для всех объектов-юзеров.
Странный критерий "возможны проблемы". Есть критический ресурс. Доступ к нему нужно синхронизировать.
Если всё сводится к инкременту-чтению-записи, то AtomicInteger просто создан для этого? Зачем изобретать что-то?

По-вашему вы получите нереальный прирост производительности, если вместо AtomicInteger.get() будете использовать прямой доступ к int полю? Или что вас смущает?
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505238
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczПо-вашему вы получите нереальный прирост производительности, если вместо AtomicInteger.get() будете использовать прямой доступ к int полю? Или что вас смущает?
Ну в общем да. Ну понятно, что не нереальный, но какой-то.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505254
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindЕсть класс сервис и его объект в единственном экземпляре, в котором есть метод который работает в много поточной среде, в нем имеется такой код:
Код: java
1.
2.
3.
4.
5.
6.
7.
		synchronized (q) {
			if (q.getVotes() == null) {
				q.setVotes(1);
			} else {
				q.setVotes(q.getVotes() + 1);
			}
		}


q - объект другого класса, их может быть множество

Как можно подобное реализовать с помощью ReentrantLock или может есть какой-то другой инструмент из concurrent? Была мысль класть Локи в ConcurrentHashMap, где ключе - объекты q, а значения - локи. Но есть проблема, объекты q - мы не можем хранить в мапе вечно, надо их от туда удалять, но нужно будет выполнять на них .unlock() и .remove() - это две операции, в итоге другой поток в промежуток между ними может начать работать со своим, вторым, локом.
Можно было бы сделать поле AromicInteger но не хочется.


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
  public Map<Object, AtomicInteger> countRepeatingElements(Object... elements) {
    ConcurrentMap<Object, AtomicInteger> result = new ConcurrentHashMap<Object, AtomicInteger>();
    for (Object element : elements) {
      result.putIfAbsent(element, new AtomicInteger(0)); //useful method that exists only in concurrent maps
      result.get(element).incrementAndGet();
    }
    return result;
  }
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505264
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindBlazkowiczПо-вашему вы получите нереальный прирост производительности, если вместо AtomicInteger.get() будете использовать прямой доступ к int полю? Или что вас смущает?
Ну в общем да. Ну понятно, что не нереальный, но какой-то.
Ну, какой-то такой, близкий к нулю, в общем.
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505362
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1MaxNevermindЕсть класс сервис и его объект в единственном экземпляре, в котором есть метод который работает в много поточной среде, в нем имеется такой код:
Код: java
1.
2.
3.
4.
5.
6.
7.
		synchronized (q) {
			if (q.getVotes() == null) {
				q.setVotes(1);
			} else {
				q.setVotes(q.getVotes() + 1);
			}
		}


q - объект другого класса, их может быть множество

Как можно подобное реализовать с помощью ReentrantLock или может есть какой-то другой инструмент из concurrent? Была мысль класть Локи в ConcurrentHashMap, где ключе - объекты q, а значения - локи. Но есть проблема, объекты q - мы не можем хранить в мапе вечно, надо их от туда удалять, но нужно будет выполнять на них .unlock() и .remove() - это две операции, в итоге другой поток в промежуток между ними может начать работать со своим, вторым, локом.
Можно было бы сделать поле AromicInteger но не хочется.


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
  public Map<Object, AtomicInteger> countRepeatingElements(Object... elements) {
    ConcurrentMap<Object, AtomicInteger> result = new ConcurrentHashMap<Object, AtomicInteger>();
    for (Object element : elements) {
      result.putIfAbsent(element, new AtomicInteger(0)); //useful method that exists only in concurrent maps
      result.get(element).incrementAndGet();
    }
    return result;
  }


и что произойдет если между
result.putIfAbsent(element, new AtomicInteger(0)); //useful method that exists only in concurrent maps
и
result.get(element).incrementAndGet();
будет вызван result.remove(element) как я указал в первом посте?
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505371
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

то есть если соотношение операций 1 \ 10 - просто чтение \ чтение с изменением, то все равно лучше сделать через atomicInteger? synchronized на столько дороже atomicInteger?
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505376
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindто есть если соотношение операций 1 \ 10 - просто чтение \ чтение с изменением, то все равно лучше сделать через atomicInteger?

Конечно.


MaxNevermindsynchronized на столько дороже atomicInteger?
Если потоков больше одного, то на очень много: 15284476
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505438
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindи что произойдет если между
result.putIfAbsent(element, new AtomicInteger(0)); //useful method that exists only in concurrent maps
и
result.get(element).incrementAndGet();
будет вызван result.remove(element) как я указал в первом посте?

сложно по куску Вашего кода понять что вы хотите сотворить ???!!!

возможно Вам нужен ThreadLocal в каждом классе или AtomicReference Решать Вам.

http://www.sql.ru/forum/1051995-1/test-synchronized-vs-reentrantlock
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505545
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ясно. Всем спасибо!
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505843
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
  public Map<Object, AtomicInteger> countRepeatingElements(Object... elements) {
    ConcurrentMap<Object, AtomicInteger> result = new ConcurrentHashMap<Object, AtomicInteger>();
    for (Object element : elements) {
      result.putIfAbsent(element, new AtomicInteger(0)); //useful method that exists only in concurrent maps
      result.get(element).incrementAndGet();
    }
    return result;
  }

Это шутка такая? :-) Создавать локальный конкурентный мап, запихивать в него атомики, а потом еще и у putIfAbsent не проверять результат - это за гранью добра и зла. Ваш пример решается вот так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  public Map<Object, AtomicInteger> countRepeatingElements(Object... elements) {
    Map<Object, Integer> result = new HashMap<>();
    for (Object element : elements) {
      Integer cnt = result.get(element);
      if (cnt == null)
        result.put(element, 0);
      else
        result.put(element, ++cnt);
    }
    return result;
  }
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505905
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvЭто шутка такая? :-) Создавать локальный конкурентный мап, запихивать в него атомики, а потом еще и у putIfAbsent не проверять результат - это за гранью добра и зла. Ваш пример решается вот так:


я ничего не понял :)но пусть будет так .
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505910
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1 ,
Ну скажем так, за тот код, что вы привели выгонят с любого собеседования, если это не джуниор позиция. Причины три:
1) Вы создали ConcurrentHashMap с которой может работать только один поток.
2) Вы работаете с локальным атомиками опять таки в однопоточном коде.
3) Вы вызываете putIfAbsent, но не смотрите на его результат.

Собственно, что полезного мог почерпнуть из этого кода ТС, непонятно :)
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505917
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv Atum1 ,
Ну скажем так, за тот код, что вы привели выгонят с любого собеседования, если это не джуниор позиция. Причины три:
1) Вы создали ConcurrentHashMap с которой может работать только один поток.
2) Вы работаете с локальным атомиками опять таки в однопоточном коде.
3) Вы вызываете putIfAbsent, но не смотрите на его результат.



ну да - просто ради того чтобы не расписывать

Код: java
1.
2.
3.
4.
5.
      if (cnt == null)
        result.put(element, 0);
      else
        result.put(element, ++cnt);
    }



:)

Собственно, что полезного мог почерпнуть из этого кода ТС, непонятно :)

-> ему только одному известно :

Код: java
1.
2.
3.
4.
5.
6.
7.
		synchronized (q) {
			if (q.getVotes() == null) {
				q.setVotes(1);
			} else {
				q.setVotes(q.getVotes() + 1);
			}
		}



с таким же успехом можно было обернуть все это в Lock вместо synchronized ?

или оставить как есть ? чем плохо такое решение ?

это узкое горло? там идет большая конкуренция за ресурс , этот код в каком то синглетоне ?... вопросы можно продолжать ...
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38505967
Фотография dmitriyche
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermind,

Если у вас есть возможность изменить класс объекта q, то можно вашу задачу решить вот так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
import java.util.concurrent.atomic.AtomicInteger;

public class Q {
    private AtomicInteger votes;

    public Q(int votes) {
        this.votes = new AtomicInteger(votes);
    }

    public int getVotes() {
        return votes.get();
    }

    public int incrementVotes() {
        return votes.incrementAndGet();
    }

}


Использовать можно вот так (вместо synchronized и ReentrantLock):
Код: java
1.
q.incrementVotes();
...
Рейтинг: 0 / 0
Как использовать ReentrantLock вместо Synchronized в данном случае?
    #38506163
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindBlazkowiczПо-вашему вы получите нереальный прирост производительности, если вместо AtomicInteger.get() будете использовать прямой доступ к int полю? Или что вас смущает?
Ну в общем да. Ну понятно, что не нереальный, но какой-то.

А вы учли, что при чтении без синхронизации вы скорее всего теряете видимость изменений? Например, поле инкрементировалось 10 раз, а getVotes() вам вернет только 5 (в этом случае вооще getVotes вне синхронизированнхы блоков можно на return 0 заменить, может быть консистентно с вашей моделью программы). Я не утверждаю, что так будет. Но чтобы так не было, требуются специальные действия. На этом фоне AtomicInteger заметных проблем с производительностью не даст (и при этом он обеспечивает видимость изменений).
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Как использовать ReentrantLock вместо Synchronized в данном случае?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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