我必须等到HashMap
键的值从另一个线程改变,然后再继续请求处理。
发布于 2022-04-13 13:54:52
我认为最灵活的解决方案将是实现观测器模式。
自JDK版本9以来,Note就不再推荐使用Observer
和Observable
,即使您使用的是Java 8,也不要使用它们。它们的问题是,它们的名称以及Observer
的方法名称Observer
没有向代码的读者说明触发的事件以及随后可能发生的操作。
从图中可以看到,subject应该包含观察者(或侦听器)的集合。
在您的示例中,主题应该是类,其中包含您想要侦听的HashMap
更新。不要扩展映射,而是用类包装它。因为如果您选择扩展HashMap
,您的代码将依赖于它的实现。而且,HashMap
中的任何更改,例如,添加了新方法或改进了新方法,都可能破坏代码(这个主题在乔舒亚·布洛赫的“有效Java”一书中讨论过,有关更多信息,请看一看)。
假设我们有一个类OrderManager
,它维护一个Order
的映射,这个类将是一个subject。
一些服务,如LoggingManagerand maybe some more needs to notified new order was added. These are our ***observers***. All these classes an interface, let's say
OrderAddedListenerthat defines a single method
onOrderAdded(Order,BillingManager
)‘,这是我们感兴趣的事件。
Note__,如果您需要侦听其他事件,如删除或更新,则需要定义一个新接口,该方法负责处理每个目标事件,正如接口隔离原则所示。
OrderManager
必须有一组观察者。添加新订单时,subject将遍历观察者的集合,并对每个观察者调用onOrderAdded()
方法。
为了添加一个需要侦听添加顺序事件的观察者,OrderManager
必须定义一个方法来注册它,同时也是一个很好的做法,添加另一个方法来注销已经注册的观察者,以便在您不再需要它时删除它。
异步处理
Note,在本例中,事件是在同一个线程中处理的。如果观察者执行的操作是昂贵的,或者可能阻塞线程,为了异步地触发它们,您可以创建一个类,该类将实现Runnable
并保存对观察者和事件的引用(命令添加/更新),方法run()
将触发观察者。当发生新事件时,OrderManager
不应该在每个观察者上调用onOrderAdded()
,而是应该创建该类的一个新实例,通过向其构造函数传递一个观察者和一个新的顺序来实现runnable,然后创建和触发一个新线程。
这是一种简化的方法。但我想这会给你一个大致的理解。
实施实例
这可能是什么样子:
public class OrderManager {
private Map<Long, Order> orderById = new HashMap<>();
private Set<OrderAddedListener> listeners = new HashSet<>();
public void addOrder(Order order) {
// notifying observers
listeners.forEach(observer -> observer.onOrderAdded(order));
orderById.put(order.getId(), order);
}
// more methods like removeOrder(), getOrderCount() etc.
public boolean registerOrderAddedListener(OrderAddedListener listener) {
return listeners.add(listener);
}
public boolean unregisterOrderAddedListener(OrderAddedListener listener) {
return listeners.remove(listener);
}
}
public interface OrderAddedListener {
void onOrderAdded(Order order);
}
public class LoggingManager implements OrderAddedListener {
private Logger logger;
@Override
public void onOrderAdded(Order order) {
// logger.log();
System.out.println("Log message has been written");
}
}
public class BillingManager implements OrderAddedListener {
private BillingService billingService;
@Override
public void onOrderAdded(Order order) {
// billingService.sendBill(order);
System.out.println("A bill has been sent");
}
}
main()
-一个简单的演示
public static void main(String[] args) {
OrderManager orderManager = new OrderManager();
orderManager.registerOrderAddedListener(new LoggingManager());
orderManager.registerOrderAddedListener(new BillingManager());
orderManager.addOrder(new Order());
}
输出
A log message has been written
A bill has been sent
https://stackoverflow.com/questions/71854454
复制相似问题