如何聆听Hashmap的更改Java中的特定键的值

发布于 2025-01-21 03:24:09 字数 57 浏览 0 评论 0原文

我必须等到 HashMap 键的值从另一个线程更改,然后必须继续请求处理。

I have to wait till the HashMap key's value change from another thread and have to continue the request processing after that.

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

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

发布评论

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

评论(1

心作怪 2025-01-28 03:24:09

我认为最灵活的解决方案是实现观察者模式

注意 build-inn Interfaces 观察者可观察自JDK版本9都被弃用。即使您正在使用Java 8不要使用它们。他们的问题是他们的名称以及observer的方法 不向代码的读者讲任何事件的内容触发以及可能采取什么样的动作。

从图中可以看到屁股,主题应包含观察者的收集 (或侦听器)。

在您的情况下,应该集体包含hashmap您要收听的更新。不要延长地图,而是用班级包装。因为如果您选择扩展hashmap您的代码将取决于其实现。例如,hashmap的任何更改,例如,添加了新方法或改进了现有方法,都可能破坏您的代码( 本主题在Joshua blochtake的“有效Java”一书中介绍,请有一个查看更多信息)。

因此,假设我们有一个类OrderManager维护Order s的地图。此类将是A 主题

添加了几个服务,例如BillingManager,LoggingManager ,也许还需要更多需要通知新订单的服务。这些是我们的***观察者***。所有这些类是接口,假设 orderaddedlistener 定义单个方法 onorderAdded(订单订单)``这就是我们感兴趣的事件。

note ,如果您需要收听其他事件,例如删除或更新,则需要用一个针对每个目标事件的方法定义一个新界面,因为接口隔离原则建议。

order> ordersmanager >必须有一个观察者的集合。当添加新订单时,主题通过观察者的收集和调用OnorderAdded()方法进行迭代。

为了添加一个观察者,需要收听订单添加的事件ordermanager必须定义一种注册它的方法,也是添加另一个以登记已注册的观察者的好习惯当您不再需要时,可以将其删除。

异步处理

注意,在此示例中,事件正在相同的线程中进行处理。如果观察者执行的操作是昂贵的或可能会阻止线程,则为了异步发射它们,您可以创建一个可以实现运行的类,并保留对 observer 和<的参考。 em> event (订购添加/更新),方法run()将触发观察者。当发生新事件时,ordermanager而不是在每个观察者上调用onorderadded()应创建一个通过传递观察者和a 新订单 对其构造函数,然后创建和启动新线程。

这是一种简化的方法。但是我想这将使人们对总体想法有所了解。

实现示例

表明:

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

I think the most flexible solution will be to implement the Observer pattern.

enter image description here

Note that build-inn interfaces Observer and Observable are deprecated since JDK version 9. Even if you are using Java 8 don't use them. The problem with them is that their names as well as the method name update() of the Observer don't tell anything to the reader of the code about the event that was triggered and what kind of actions might follow.

Ass you can see from the diagram, the subject should contain a collection of observers (or listeners).

The subject in your case should be class contains a HashMap updates of which you want to listen. Don't extend the map, wrap it with your class instead. Because if you choose to extend HashMap your code will become dependent on its implementation. And any changes in the HashMap, for instance, new methods were added or existing were improved could break your code (this topic is covered in the book "Effective Java" by Joshua Blochtake, have a look at it for more information).

So let's say we have a class OrderManager that maintains a map of Orders. This class will be a subject.

A couple of services like BillingManager, LoggingManagerand maybe some more needs to notified new order was added. These are our ***observers***. All these classes an interface, let's sayOrderAddedListenerthat defines a single methodonOrderAdded(Order order)`, that's the event we are interested in.

Note, if you need to listen to other events like removal or update, you need to define a new interface with a method responsible for that for every target event as the Interface segregation principle suggests.

OrderManager has to have a collection of observers. When a new order is being added, subject iterates through the collection of observers and invokes onOrderAdded() method on each of them.

In order to add an observer that need to listen to the order-added event OrderManager has to define a method to register it, and it's also good practice to add another one to unregister the observer that has registered to be able to remove it when you no longer need it.

Asynchronous processing

Note, that in this example, events are being processing in the same thread. If actions performed by observers are costful or might block the thread, in order to fire them asynchronously you can create a class that will implement Runnable and hold references to the observer and event (order the was added/updated), and method run() will trigger the observer. And when a new event occurs, OrderManager instead of invoking onOrderAdded() on each observer should create a new instance of that class implementing runnable by passing an observer and a new order to its constructor and then create and fire a new thread.

It's a simplified approach. But I guess it'll give an understanding of the general idea.

Implementation example

That how it might look like:

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() - a simple demo

public static void main(String[] args) {
    OrderManager orderManager = new OrderManager();
    orderManager.registerOrderAddedListener(new LoggingManager());
    orderManager.registerOrderAddedListener(new BillingManager());
    orderManager.addOrder(new Order());
}

Output

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