Java:数据同步问题

Posted

技术标签:

【中文标题】Java:数据同步问题【英文标题】:Java: data synchronization issue 【发布时间】:2021-09-12 13:48:05 【问题描述】:

我的 Java 程序向客户端的 API 发出请求,而客户端的 API 将在不规则时间间隔(即不是每 5 秒/10 秒,有时是 1 秒或 5 秒)返回一个键值对.

并且我已将自己的代码(HashMap)插入到客户端 API 代码中以存储所有键值对。

我的目标是运行下面标有“!!!”的代码只要 Hashmap 条件匹配。 我不是 Java 数据同步方面的专家。请注意,Thread.Sleep(3000) 不起作用,因为键值对会在不规则的时间间隔内更新。而且,同一个key的值也会随着时间而改变。 我尝试运行下面的程序,它立即跑过标有“!!!”的代码块,这不是我想要实现的。

解决这个问题最有效的解决方案是什么?

Class Testing
    public static void main(String[] args)
        // connect to API...
        ClientAPI clientAPI = new ClientAPI();
        clientAPI.connect();

        // make a request to retrieve an update of a HashMap
        clientAPI.requestHashMapUpdate();

        // !!! execute the following block of code only if hashmap contains a specific key value pair, i.e. key1, 1 
        // if hashmap does not contain key or the key-value pair do not match , then wait until the key-value pair are matched and run the code
        if(clientAPI.getMyHashMap().containsKey("key1"))
            if(clientAPI.getMyHashMap().get("key1") == 1)
                    System.out.println("Print Me only if key and value are matched !!!!!!!!");
            
        

    



Class ClientAPI
    private HashMap<String,Integer> myHashMap;
    
    // Constructor
    public clientAPI()
            myHashMap = new HashMap<String,Integer>();
    

    // callback function of API's requestHashMapUpdate method
    public void updateHashMapKeyValuePair(String key, int value)
        System.out.println("Key:" + key + ", Value: " + value);
        // code i wrote to update hashmap with key value pair returned from API
        myHashMap.put(key,value);
    

    // my code to retrieve the latest snapshot of myHashMap
    public HashMap<String,Integer> getMyHashMap()
        return myHashMap;
    


【问题讨论】:

除了每次更新时检查 HashMap 的内容之外,您实际上并没有什么可以做的。如果您在更新时无法收到通知,那么除了投票之外,您真的无能为力。 有没有办法在hashmap更新时通知程序? 不是天生的。只需通过更新地图的代码通知客户端即可。 【参考方案1】:

覆盖您的客户端 API(如果它未对扩展关闭):

class MyClientAPI extends ClientAPI 
    ...
    @Override
    public void updateHashMapKeyValuePair(String key, int value) 
        super.updateHashMapKeyValuePair(key, value);
        if("key1".equals(key) && 1 == value)
            System.out.println("Print Me only if key and value are matched !!!!!!!!");
    
    ...

然后简单地检查每个新的值。

要使用它,只需改变

ClientAPI clientAPI = new MyClientAPI();

解决此问题的另一种方法是为您的ClientAPI 类提供注册侦听器的能力

interface UpdateHashMapKeyValuePairListener 
    void digestUpdate(String key, int value);


class ClientAPI 
    ...
    private List<UpdateHashMapKeyValuePairListener> listeners = new ArrayList();
    ...
    public void registerUpdateListener(UpdateHashMapKeyValuePairListener u) 
        listeners.add(u);
    
    ...
    public void updateHashMapKeyValuePair(final String key, final int value) 
        listeners.forEach(u -> u.digestUpdate(key, value));
        ...
    
    ...

那么,任何想知道新值何时进入的人,只需实现这个接口,例如

...
clientAPI.registerUpdateListener((key, value) -> 
    if("key1".equals(key) && 1 == value)
        System.out.println("Print Me only if key and value are matched !!!!!!!!");
);
clientAPI.connect();
...

【讨论】:

【参考方案2】:

每次更新时检查 HashMap 的内容。为此,您可以在 Testing 类中注册一个侦听器,以在每次 HashMapClientAPI 类中更新时触发。

首先定义监听器的功能接口:

 @FunctionalInterface
  public interface OnUpdateMapListener 
      void onUpdateMap(Map<String, Integer> map);
  

然后在ClientAPI中添加监听器

 public class ClientAPI 
        private HashMap<String, Integer> myHashMap;
        private OnUpdateMapListener onUpdateMapListener;

定义onMapUpdate方法在ClientAPI中传递监听器的body:

public void onMapUpdate(OnUpdateMapListener onUpdateMapListener) 
        this.onUpdateMapListener = onUpdateMapListener;

并在updateHashMapKeyValuePair中的HashMap更新时触发监听器

public void updateHashMapKeyValuePair(String key, int value) 
  System.out.println("Key:" + key + ", Value: " + value);
  // code i wrote to update hashmap with key value pair returned from API
   myHashMap.put(key, value);
   onUpdateMapListener.onUpdateMap(myHashMap);
 

在 main 方法中注册监听器并检查地图内容。每次ClientAPIupdateHashMapKeyValuePair 方法中接收到新的地图内容时都会触发此事件:

clientAPI.onMapUpdate(stringIntegerHashMap -> 
      // !!! the following code is executed every time the hashMap is updated
       if (clientAPI.getMyHashMap().containsKey("key1")) 
           if (clientAPI.getMyHashMap().get("key1") == 1) 
             System.out.println("Print Me only if key and value are matched !!!!!!!!");
           
      
);

ClientAPI类:

public class ClientAPI 
    private HashMap<String, Integer> myHashMap;

    private OnUpdateMapListener onUpdateMapListener;

    // Constructor
    public ClientAPI() 
        myHashMap = new HashMap<String, Integer>();
    

    // callback function of API's requestHashMapUpdate method
    public void updateHashMapKeyValuePair(String key, int value) 
        System.out.println("Key:" + key + ", Value: " + value);
        // code i wrote to update hashmap with key value pair returned from API
        myHashMap.put(key, value);
        onUpdateMapListener.onUpdateMap(myHashMap);
    

    // my code to retrieve the latest snapshot of myHashMap
    public HashMap<String, Integer> getMyHashMap() 
        return myHashMap;
    

    public void requestHashMapUpdate() 
      //.....
    

    public void onMapUpdate(OnUpdateMapListener onUpdateMapListener) 
        this.onUpdateMapListener = onUpdateMapListener;
    

Testing类:

 public static void main(String[] args) 
      // connect to API...
        ClientAPI clientAPI = new ClientAPI();
        clientAPI.connect();

        // make a request to retrieve an update of a HashMap
       clientAPI.requestHashMapUpdate();

        clientAPI.onMapUpdate(stringIntegerHashMap -> 
            // !!! the following code is executed every time the hashMap is updated
            if (clientAPI.getMyHashMap().containsKey("key1")) 
                if (clientAPI.getMyHashMap().get("key1") == 1) 
                    System.out.println("Print Me only if key and value are matched !!!!!!!!");
                
            
        );

        clientAPI.updateHashMapKeyValuePair("key1", 1);
        clientAPI.updateHashMapKeyValuePair("key1", 2);
    

结果:

Key:key1, Value: 1
Print Me only if key and value are matched !!!!!!!!
Key:key1, Value: 2

【讨论】:

以上是关于Java:数据同步问题的主要内容,如果未能解决你的问题,请参考以下文章

java 数据同步 日志怎么记

java数据同步陷阱

Java:数据同步问题

[java同步数据库表]javaoracle怎么实现数据库同步

[java数据库同步]java实现同步数据

Java多线程:线程同步详解