java中在某些条件下阻塞线程

发布于 2024-12-16 00:50:40 字数 261 浏览 3 评论 0原文

也许这是一个非常愚蠢的问题,但请听我说完。我有一个用例,我收到许多并发请求,要求针对特定输入日期执行某些操作。如果同一输入日期收到两个并发请求,则在前一个请求完全完成之前,后续请求不应继续进行(出于充分的理由)。使用标准 java.util.concurrent 组件来实现此目的的最佳方法是什么?我最初的想法是拥有一个 LockFactory,它将出售锁并保留一个副本以表明它正在使用,并且后续请求将在其上等待()。然而,这似乎有很多样板代码 - 有什么更简单的技巧让我困惑吗?

提前致谢!

Maybe this is a really dumb question, but please hear me out. I have a use case where I get many concurrent requests to do something for a particular input date. If there are two concurrent requests received for the same input date, the subsequent request should not proceed till the prior request has finished completely (for good reasons). What is the best way to use standard java.util.concurrent components to achieve this? My initial thoughts were around having a LockFactory which will vend locks and keep a copy to indicate that it is in use and on which the subsequent request will await(). However, this seems to have lot of boiler-plate code - any simpler trick that is eluding me?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

丢了幸福的猪 2024-12-23 00:50:40

您可以对日期时间的各个锁进行哈希处理。

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(); 

之类的操作

You can hash individual locks on the date's time.

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;
}

If you need the same day and not necessarily the exact date in milliseconds you can do something like

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;
}

Then any request that needs mutual exclusion on a date

Date date = ...;

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

and so forth

孤云独去闲 2024-12-23 00:50:40

在我看来,您必须将请求排队并一次处理一个。那么也许来自 java.util.concurrent 的 BlockingQueue ?

Sounds to me like you have to queue up your requests and process them one at a time. So perhaps a BlockingQueue from java.util.concurrent?

妄司 2024-12-23 00:50:40

我假设您已经拥有一个系统,其中线程可以接受输入请求并处理它们,而不会丢失或重复任何内容,从而解决任何锁定问题。然后,您需要的只是每个线程在某处记录其当前正在处理的事情的输入日期。当线程检查输入请求时,它首先检查日期,查看当前是否正在处理具有该日期的任何请求,如果是,则将该请求留在队列中并处理下一个请求。

您将需要一定程度的锁定,以确保在测试时“当前正在处理的条目”不在更新过程中。

I assume you already have a system in which threads can take input requests and process them, without missing or duplicating any, taking care of any locking issues. All you then need is for each thread to record somewhere the input date of the thing it is currently working on. When a thread examines an input request it first checks the date, looks to see if any requests with that date are currently being processed, and if they are then it leaves that request in the queue and takes the next one.

You will need a certain amount of locking to ensure that the 'currently working on entry' isn't in the process of being updated when you test it.

記憶穿過時間隧道 2024-12-23 00:50:40

您需要创建一个 ThreadPoolExecutor 来在多个线程中执行请求。您还需要有一个现在正在处理的输入日期列表。该列表应该具有同步访问器和 putIfAbsent 方法。在将任务发送到队列之前,请检查其输入日期是否现在尚未处理。如果现在正在处理,则将此任务移至队列末尾并尝试运行下一个任务。任务完成后,从列表中删除其输入日期。

You need to create a ThreadPoolExecutor to perform requests in several threads. Also you need to have a list of input dates, that are processed now. This list should have synchronous accessors and putIfAbsent method. Before sending a task to queue check that it's input date is not processed now. If it is processed now, move this task to the end of the queue and try to run next task. When task is completed, remove its input date from the list.

诗酒趁年少 2024-12-23 00:50:40

您正在寻找的简单技巧是线程池“按顺序处理”模式。 这是一个线程解释该模式以及实现该模式的各种解决方案

The simple trick you're looking for is the thread pool "with in order processing" pattern. Here is a thread which explain the pattern and various solutions to implement it

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文