Давайте представим, что вы параноик, и параноик вдвойне, когда дело касается многопоточности. Предположим, что вы делаете backend некого функционала приложения, а приложение переодически дергает на вашем серверы какие-то методы. Все вроде хорошо, но есть одно но. Что если ваш функционал напрямую зависит от каких-либо других данных, того же банального профиля например? Встает вопрос, как гарантировать то, что сценарий отработает именно так, как вы планировали и не будет каких-либо сюрпризов? Транзакции? Да это можно использовать, но что если Вы фантастический параноик и уже представляете как к вам на сервер летит 10 запросов к одному методу от разных клиентов и все строго в одно время. А в этот момент бизнес-логика данного метода завязана на 100500 разных данных. Как всем этим управлять? Можно просто синхронизировать метод и все. Но что если летят еще и те запросы, держать которые нет смысла? Тут уже начинаются костыли. Я пару раз уже задавался подобным вопросом, и были интересно, ведь задача до абсурда простая и повседневная (если вы заботитесь о том, чтобы не было логических багов конечно же ). Сегодня решил подумать, как это можно очень просто и без костылей реализовать. И решение вышло буквально на 100 строк кода.
Немного наглядного примера
Давайте предположим, что есть водитель и есть пассажир. Водитель не может менять машину до тех пор, пока клиент, например подтверждает поездку. Это что получается, клиент соглашался на поездку с одними характеристиками машины, а по факту у водителя другая машина? Не дела! Можно организовать что-то подобное:
String result = l.lock(new ArrayList<Locker.Item>() {{
add(new Locker.Item(SimpleType.TRIP, 1));
add(new Locker.Item(SimpleType.USER, 2));
}}, () -> {
// Тут выполняем отмену поездки и держим водителя на привязи
// Кстати если кто-то где-то вызовет USER=2 (водитель), то он также будет ждать
// ну или кто-то обратится к поездке TRIP=1
// А если обратится к USER=3, то уже все будет нормально
// так как никто не блокировал третьего пользователя
return "Тут любой результат ";
});
Элегантно и просто!
→ Исходники тут
Камнями не бросаться! )
Источник статьи: https://habr.com/ru/post/562724/
Немного наглядного примера
Давайте предположим, что есть водитель и есть пассажир. Водитель не может менять машину до тех пор, пока клиент, например подтверждает поездку. Это что получается, клиент соглашался на поездку с одними характеристиками машины, а по факту у водителя другая машина? Не дела! Можно организовать что-то подобное:
String result = l.lock(new ArrayList<Locker.Item>() {{
add(new Locker.Item(SimpleType.TRIP, 1));
add(new Locker.Item(SimpleType.USER, 2));
}}, () -> {
// Тут выполняем отмену поездки и держим водителя на привязи
// Кстати если кто-то где-то вызовет USER=2 (водитель), то он также будет ждать
// ну или кто-то обратится к поездке TRIP=1
// А если обратится к USER=3, то уже все будет нормально
// так как никто не блокировал третьего пользователя
return "Тут любой результат ";
});
Элегантно и просто!
→ Исходники тут
Камнями не бросаться! )
Источник статьи: https://habr.com/ru/post/562724/