簡體   English   中英

如何在 Spring 引導中制作同步 rest controller?

[英]How to make a synchronous rest controller in Spring boot?

我有一個 controller 我想同步處理請求。 如果該方法同時收到多個請求,我希望該方法同步並一個一個地處理它們,而不是同時處理它們。

add 方法接收一個“num”並檢查 nums 列表以查看列表中是否存在“num”。 如果已經存在,則不添加“num”,如果不存在,則添加“num”。 我想讓這個方法同步,這樣如果兩個添加請求同時帶有相同的數字,第一個請求將執行並返回“添加的數字”,第二個請求將返回“未添加的數字”。 我該怎么做? 使用 java“同步”關鍵字?

@RestController
@RequestMapping(path="/numberList")
public class ListController {
   
   @PostMapping("/add")
   public String add(@RequestParam(name="num", required=true)int num) {
      boolean matches = false;
      ​
      ​for(int i : RuntimeMetrics.getNums()) {
         if(i.equals(num) {
            matches = true;
         }            
      ​}
      
      if(matches) {
         return "number not added";
      }
      else{
         RuntimeMetrics.getNums().add(num);
         return "number added";
      }      
   }
}
public class RuntimeMetrics {
   private static ArrayList<Integer> nums = new ArrayList<Integer>();
  ​
   ​public static ArrayList<Integer> getNums(){
      ​return nums;
   ​}
}

您當前的實現非常非原子。 for循環可以為兩個甚至更多具有相同數量的請求提供false

最簡單的方法是添加某種並發數據結構,允許對您的列表進行訪問控制。

@RestController
@RequestMapping(path="/numberList")
public class ListController {
   private static final Set<Integer> ADDED_NUMBERS = ConcurrentHashMap.newKeySet(); // concurrent set implementation in Java

   @PostMapping("/add")
   public String add(@RequestParam(name="num", required=true) final int num) {
      if(ADDED_NUMBERS.add(num)) {
         RuntimeMetrics.getNums().add(num);
         return "number added";
      }
      else {
         return "number not added";
      }      
   }
}

並發Set實現確保原子add 即使有數百個具有相同編號的同時請求,也只有一個會返回“添加的編號”。

一種經典的列表synchronous方法是可能的,但效率要低得多,而且非常單線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM