簡體   English   中英

在java中的某些條件下阻塞線程

[英]block threads on certain conditions in java

也許這是一個非常愚蠢的問題,但請聽我說。 我有一個用例,我得到許多並發請求,為特定的輸入日期做某事。 如果在同一輸入日期收到兩個並發請求,則后續請求不應繼續,直到先前請求完全完成(有充分理由)。 使用標准java.util.concurrent組件來實現此目的的最佳方法是什么? 我最初的想法是圍繞一個LockFactory來銷售鎖並保留一份副本以表明它正在使用中並且隨后的請求將等待()。 然而,這似乎有很多鍋爐板代碼 - 任何簡單的技巧,是在逃避我?

提前致謝!

聽起來像你必須排隊你的請求並一次處理一個。 那么也許來自java.util.concurrent的BlockingQueue?

您需要創建一個ThreadPoolExecutor來在多個線程中執行請求。 您還需要有一個輸入日期列表,現在處理。 此列表應具有同步訪問器和putIfAbsent方法。 在將任務發送到隊列之前檢查它的輸入日期是否現在未處理。 如果現在處理它,將此任務移動到隊列的末尾並嘗試運行下一個任務。 任務完成后,從列表中刪除其輸入日期。

我假設您已經有一個系統,其中線程可以接收輸入請求並處理它們,而不會丟失或重復任何請求,從而解決任何鎖定問題。 然后,您需要的是每個線程在某處記錄當前正在處理的事物的輸入日期。 當線程檢查輸入請求時,它首先檢查日期,查看當前是否正在處理具有該日期的任何請求,如果它們是,則它將該請求留在隊列中並獲取下一個請求。

您需要一定量的鎖定,以確保在測試時不會更新“當前正在進行的工作”。

您可以在日期的時間哈希個別鎖。

private static final ConcurrentMap<Long,Lock> dateLock = new ConcurrentHashMap<Long,Lock>();

public static Lock getLock(Date date){
  Lock lock = dateLock.get(date.getTime());  
  if(lock == null){
    Lock lock = new ReentrantLock();  
    Lock temp =dateLock.putIfAbsent(lock); 
    lock = temp == null ? lock : temp;
  }
 return lock;
}

如果您需要同一天,而不一定是確切的日期(以毫秒為單位),您可以執行類似的操作

private static final ConcurrentMap<String,Lock> dateLock = new ConcurrentHashMap<String,Lock>();

public static Lock getLock(Date date){ 
  String formattedDate = new SimpleDateFormat("MM\dd\yyyy").parse(date);
  Lock lock = dateLock.get(formattedDate);  
  if(lock == null){
    Lock lock = new ReentrantLock();  
    Lock temp =dateLock.putIfAbsent(lock); 
    lock = temp == null ? lock : temp;
  }
 return lock;
}

然后任何需要在日期互斥的請求

Date date = ...;

Lock lock = getLock(date);
lock.lock(); 

等等

你正在尋找的簡單技巧是線程池“with in order processing”模式。 這是一個解釋模式和實現它的各種解決方案的線程

暫無
暫無

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

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