#java #spring #spring-boot #spring-mvc #synchronized
#java #весна #spring-boot #spring-mvc #синхронизированный
Вопрос:
@Slf4j
@RestController
public class DemoController {
@GetMapping
public String testStr(String str) {
String key = UUID.randomUUID().toString();
log.info("testStr start {} {}", str, key);
synchronized (str.intern()) {
log.info("testStr in {} {}", str, key);
Thread.sleep(5000);
}
log.info("testStr end {} {}", str, key);
return str;
}
}
Когда я вызываю с двумя запросами ?str=aaa
, журнал выглядит так:
testStr start aaa 3bbb03e3-84d9-4816-b275-de59657bd810
testStr in aaa 3bbb03e3-84d9-4816-b275-de59657bd810
... after 5 sec
testStr end aaa 3bbb03e3-84d9-4816-b275-de59657bd810
testStr start aaa b4f07a65-e37e-4471-be79-877a8d529f04
testStr in aaa b4f07a65-e37e-4471-be79-877a8d529f04
... after 5 sec
testStr end aaa b4f07a65-e37e-4471-be79-877a8d529f04
Но я думаю, что это должно быть
testStr start aaa 3bbb03e3-84d9-4816-b275-de59657bd810
testStr in aaa 3bbb03e3-84d9-4816-b275-de59657bd810
testStr start aaa b4f07a65-e37e-4471-be79-877a8d529f04
... after 5sec
testStr in aaa b4f07a65-e37e-4471-be79-877a8d529f04
testStr end aaa 3bbb03e3-84d9-4816-b275-de59657bd810
... after 5 sec
testStr end aaa b4f07a65-e37e-4471-be79-877a8d529f04
Другая часть: журнал testStr start...
должен регистрироваться до 5 секунд.
Я что-то пропустил?
Кстати, я тестирую этот код с помощью простого main без spring, тогда все работает так, как ожидалось.
основной код
public static void main(String[] args) {
DemoController demoController = new DemoController();
new Thread(()->{
String result = demoController.testStr("aaa");
log.info("result1 {}", result);
}).start();
new Thread(()->{
String result = demoController.testStr("aaa");
log.info("result2 {}", result);
}).start();
}
Комментарии:
1. То есть вы по сути хотите сказать, что java не знает, как синхронизировать? Поскольку это не имеет ничего общего ни с Spring, ни с Spring Boot, но как синхронизация применяется JVM.
2. Извините, но я не понимаю, о чем вы говорите. Если это проблема с JVM, почему я получил другой результат при запуске с чистым main?
3. Main однопоточный, это несколько потоков. Syncronized — это функция jvm, и то, как и что это блокирует, зависит от jvm, а не от spring.
4. Мой основной — это тоже несколько потоков, я обновляю свой вопрос: добавить основной класс. Пожалуйста, проверьте еще раз.
5. Если вы попробуете один из ваших 2 запросов на вкладке «инкогнито», а другой — на вкладке «Обычный», вы получите искомый результат.