Здравствуйте, GarryIV, Вы писали:
GIV>Здравствуйте, Aleksei_Lekomtsev, Вы писали:
A_L>>Вместо long думаю можно использовать AtomicLong. Не уверен на счет подойдет ли тут synchronized для increment()... GIV>https://foojay.io/today/thread-safe-counter-in-java-a-comprehensive-guide/
GIV>LongAdder производительное и простое решение (лучше AtomicLong), а так вариантов много включая synchronized.
А если сравнивать AtomicLong и synchronized, есть ли у AtomicLong преимущества, например по performance?
Если использовать synchronized, то при заходе в метод захватывается монитор объекта, т.е. если будут еще методы synchronized, то
они будут ждать очереди пока отработает первый. А если использовать AtomicLong, то вроде как такой сложности не должно возникнуть...
Re[3]: Как исправить код, чтобы он работал в многопоточном режиме?
Здравствуйте, Aleksei_Lekomtsev, Вы писали:
GIV>>LongAdder производительное и простое решение (лучше AtomicLong), а так вариантов много включая synchronized.
A_L>А если сравнивать AtomicLong и synchronized, есть ли у AtomicLong преимущества, например по performance?
да, AtomicLong это CAS — без блокировок, которые тормозные
A_L>Если использовать synchronized, то при заходе в метод захватывается монитор объекта, т.е. если будут еще методы synchronized, то A_L>они будут ждать очереди пока отработает первый. А если использовать AtomicLong, то вроде как такой сложности не должно возникнуть...
все так
но LongAdder еще лучше
WBR, Igor Evgrafov
Re: Как исправить код, чтобы он работал в многопоточном режиме?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Aleksei_Lekomtsev, Вы писали:
A_L>>
A_L>>@RestController
A_L>>public class Counter {
A_L>> private long counter = 0;
A_L>> @GetMapping("/increment")
A_L>> public long increment() {
A_L>> return ++counter;
A_L>> }
A_L>>}
A_L>>
PD>Хм. Что-то я не понимаю. Это же инстансное поле класса. С чего ты решил, что экземпляр класса будет один ?
PD>Наверное, нужно static, и тогда AtomicLong
Я честно говоря не знаю как Spring работает в этом случае. Т.е. если я правильно понимаю, то если будут 2 get-запроса для
данного endpoint, то Spring создаст 2 threads, которые будут работать с одним и тем же полем counter...но это не точно)
Re[3]: Как исправить код, чтобы он работал в многопоточном режиме?
Здравствуйте, Aleksei_Lekomtsev, Вы писали:
A_L>Я честно говоря не знаю как Spring работает в этом случае. Т.е. если я правильно понимаю, то если будут 2 get-запроса для A_L>данного endpoint, то Spring создаст 2 threads, которые будут работать с одним и тем же полем counter...но это не точно)
Spring controllers are singletons (there is just one instance of each controller per web application) just like servlets.
а с другой
Be aware that they'll only be singletons per context, and that it's entirely possible to have nested contexts when working with Spring web applications, and that by duplicating a package-scan you might end up with multiple instances of the same controller.
Так что я бы поставил static и не парился.
With best regards
Pavel Dvorkin
Re[4]: Как исправить код, чтобы он работал в многопоточном р
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Так что я бы поставил static и не парился.
Здесь уже вступаю в игру архитектурные правила. Обычно в контроллерах не размещают бизнес-логику, тем более stateful. Она выносится в сервисный слой или в инкапсулируется DDD-обьектом. Они и отвечают за гарантии, и конфигуряться специально для обеспечения Singleton-логики этих данных. А конфигурить scope контроллера для этого нельзя, это смертный грех архитектуры. Эти рассуждения показывают, что ты не просто сам язык Java Core знаешь, но и знаком с парадигмами энтерпрайз-разработки на джаве.
Здравствуйте, gyraboo, Вы писали:
G>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Так что я бы поставил static и не парился.
G>Здесь уже вступаю в игру архитектурные правила. Обычно в контроллерах не размещают бизнес-логику, тем более stateful. Она выносится в сервисный слой или в инкапсулируется DDD-обьектом. Они и отвечают за гарантии, и конфигуряться специально для обеспечения Singleton-логики этих данных. А конфигурить scope контроллера для этого нельзя, это смертный грех архитектуры.
класс со static полем — рассматривает как stateful? stateful к свойству объекта относится?
П.С. Думаю поторопился с вопросом)Если у класса есть поля, то это stateful, если ничего не напутал)
Здравствуйте, gyraboo, Вы писали:
G>Здесь уже вступаю в игру архитектурные правила. Обычно в контроллерах не размещают бизнес-логику, тем более stateful. Она выносится в сервисный слой или в инкапсулируется DDD-обьектом. Они и отвечают за гарантии, и конфигуряться специально для обеспечения Singleton-логики этих данных. А конфигурить scope контроллера для этого нельзя, это смертный грех архитектуры. Эти рассуждения показывают, что ты не просто сам язык Java Core знаешь, но и знаком с парадигмами энтерпрайз-разработки на джаве.
Знаком, не беспокойся ...
Я вообще предпочитаю, чтобы в методе контроллера была одна строчка — вызов метода сервиса.
Но ТС хочет так, вот я и решил выяснить, синглетон он или нет. Как-то раньше не задумывался об этом.
With best regards
Pavel Dvorkin
Re[4]: Как исправить код, чтобы он работал в многопоточном режиме?
Здравствуйте, Aleksei_Lekomtsev, Вы писали:
A_L>класс со static полем — рассматривает как stateful? stateful к свойству объекта относится?
A_L>П.С. Думаю поторопился с вопросом)Если у класса есть поля, то это stateful, если ничего не напутал)
Стейтфул объект конечно если это поле не статик. А если статик, то тут стейтлес объект, но можно сказать что стейтфул класс наверное. Так что прав наверное именно ты.
У контроллера могут быть поля, инжектируемые самим контейнером зависимости, контролируемве им, при этом объект не считается стейтфул. Стейтфул это имеется ввиду именно хранение бизнесового состояния в экземпляре класса.
Re[2]: Как исправить код, чтобы он работал в многопоточном режиме?
AL>Вместо long думаю можно использовать AtomicLong. Не уверен на счет подойдет ли тут synchronized для increment()...
Сразу обращаю внимание, что предложеная архитектура в твоем примере неверная. Счетчик должен быть не на слое представления (не в классе @RestController), а на слое бизнес-логики (@Service/@Component/@Bean). Кроме того, неплохо было бы использовать стандартное Spring-решение на базе Spring Actuator с Metrics, чтобы не городить велосипеды.
В любом случае, техническое (про архитектуру я выше написал) решение может быть любым и по уровню синхронизации (что является объектом синхронизации) и по типу велосипеда, будет ли это решение с AtomicLong или synchronized один фиг это будет работать в рамках только одной ноды/сервера в мульти-потоковом окружении. Но как только решишь распараллелить на контейнеры/виртуалки — то будет попоболь .
...<< Dementor 1.4.3 ✪ Lets Play a Game ⚀⚂⚂⚃⚅>>
Re[5]: Как исправить код, чтобы он работал в многопоточном режиме?
Здравствуйте, m2user, Вы писали:
GIV>>все так GIV>>но LongAdder еще лучше
M>У LongAdder ведь нет аналога AtomicLong.incrementAndGet, т.е. без доп. синхронизации AtomicLong он в данном случае не заменит.
угу, и получение текущего значения скорее всего убъет всю выгоду
WBR, Igor Evgrafov
Re[6]: Как исправить код, чтобы он работал в многопоточном режиме?
Здравствуйте, GarryIV, Вы писали:
GIV> M>У LongAdder ведь нет аналога AtomicLong.incrementAndGet, т.е. без доп. синхронизации AtomicLong он в данном случае не заменит. GIV> угу, и получение текущего значения скорее всего убъет всю выгоду
А если какую-то выгоду и удастся получить, то её никак не будет возможно разглядеть в условиях десятков слоёв спринга и прочего rest.