gpt4 book ai didi

java - 等待多个并行线程之一完成

转载 作者:行者123 更新时间:2023-12-01 13:25:44 28 4
gpt4 key购买 nike

这是正在发生的事情的简要描述 -

执行场景:

搜索请求 --> 检查缓存中是否存在该请求的数据 --> 如果缓存中存在,则从缓存中获取,否则从数据库中获取并放入缓存中的数据

这项工作适合以下场景

<小时/>

以下是按顺序接收请求的情况

第一个请求请求-->检查缓存(不存在,因为这是第一个请求)-->从数据库获取并放入缓存

第二个请求请求-->检查缓存(数据存在,因为先前的请求已使数据在缓存中可用)

第三个请求请求-->检查缓存(数据仍然存在)

第四个请求请求-->检查缓存(数据仍然存在)

<小时/>

但是,如果多个线程同时请求数据,则会失败。

这是并行接收请求的情况(同时)

第一个请求请求-->检查缓存(不存在,因为这是第一个请求)-->从数据库获取并放入缓存

第二个请求请求-->检查缓存(不存在,因为这是第一个请求)-->从数据库获取并放入缓存

第三个请求请求-->检查缓存(不存在,因为这是第一个请求)-->从数据库获取并放入缓存

第四个请求请求-->检查缓存(不存在,因为这是第一个请求)-->从数据库获取并放入缓存

<小时/>

你发现问题了吗?每个线程都在访问数据库。

我没有使用任何同步块(synchronized block),因为这将使其成为顺序执行,对吧?

如何避免这一问题,以便只有一个线程访问数据库,而其他线程从缓存中选取数据(特别是在并行执行的情况下)?他们是否已经存在任何模式来解决此类问题?

我知道我将线程与请求混合在一起,但它们本质上是同一件事。

如果问题的标题看起来不好,请随意修改。

最佳答案

第一个线程发现缓存中不存在该对象,创建特殊类(一种Future)的临时对象并将其放入哈希表中。然后开始DB查询。

后续线程看到临时对象,不会查询数据库,而是排队等待结果出现。

第一个线程从数据库获取结果并通知其他线程。

Temporary对象的类可以从头开始创建,也可以基于guava的SettableFuture、java8 CompletableFuture或java5 FutureTask创建。

附录

为了确保只有一个并发线程启动数据库提取,当线程测试缓存并插入临时对象时,应该锁定整个缓存。因此,访问不同 key 的线程会相互竞争。如果访问速率较高,导致性能下降,this solution可能有帮助。它解释了可以以并行方式测试缓存。对于您的任务,应该更新解决方案,以便将获取的数据放入缓存中。

关于java - 等待多个并行线程之一完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21815848/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com