当前位置: 首页 > 知识库问答 >
问题:

Java:基于对象值的同步

邓才
2023-03-14

我想基于输入参数同步一个方法或一个块。

因此,我有一个API,它在post有效负载中有两个长类型的输入(比如id1和id2),可以是原始的,也可以是包装的),可以是JSON。这个API将被多个线程同时或随机地在不同时间调用。

现在如果第一个API调用有ID1=1和ID2=1,同时另一个API调用有ID1=1和ID2=1,它应该等待第一个API调用处理完毕后再执行第二个调用。如果第二个API调用具有不同的值组合,如ID1=1和ID2=2,则它应该在没有任何等待时间的情况下并行执行。

我不介意创建一个API资源方法也可以调用的服务方法,而不是直接在API资源方法上处理。

我使用的是spring boot Rest控制器API。

public static void main(String[] args) throws Exception {
    ApplicationContext context = SpringApplication.run(Application.class, args);
    AccountResource ar = context.getBean(AccountResource.class);
    UID uid1 = new UID();
    uid1.setFieldId(1);
    uid1.setLetterFieldId(1);
    UID uid2 = new UID();
    uid2.setFieldId(2);
    uid2.setLetterFieldId(2);
    UID uid3 = new UID();
    uid3.setFieldId(1);
    uid3.setLetterFieldId(1);
    Runnable r1 = new Runnable() {

        @Override
        public void run() {
            while (true) {
                ar.test(uid1);
            }

        }
    };
    Runnable r2 = new Runnable() {

        @Override
        public void run() {
            while (true) {
                ar.test(uid2);
            }

        }
    };
    Runnable r3 = new Runnable() {

        @Override
        public void run() {
            while (true) {
                ar.test(uid3);
            }

        }
    };
    Thread t1 = new Thread(r1);
    t1.start();
    Thread t2 = new Thread(r2);
    t2.start();
    Thread t3 = new Thread(r3);
    t3.start();

}
@Path("v1/account")
@Service
public class AccountResource {
public void test(UID uid) {
        uidFieldValidator.setUid(uid);
        Object lock;
        synchronized (map) {
            lock = map.get(uid);
            if (lock == null) {
                map.put(uid, (lock = new Object()));
            }
            synchronized (lock) {
                //some operation
            }
        }
    }
}

package com.urman.hibernate.test;

import java.util.Objects;

public class UID {
    
    private long letterFieldId;
    private long fieldId;
    private String value;
    public long getLetterFieldId() {
        return letterFieldId;
    }
    public void setLetterFieldId(long letterFieldId) {
        this.letterFieldId = letterFieldId;
    }
    public long getFieldId() {
        return fieldId;
    }
    public void setFieldId(long fieldId) {
        this.fieldId = fieldId;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    @Override
    public int hashCode() {
        return Objects.hash(fieldId, letterFieldId);
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        UID other = (UID) obj;
        return fieldId == other.fieldId && letterFieldId == other.letterFieldId;
    }
}

共有1个答案

须鸿祯
2023-03-14

您需要一个锁的集合,您可以将其保存在一个映射中,并根据需要进行分配。这里我假设您的id1和id2是字符串;适当调整。

 Map<String,Object> lockMap = new HashMap<>();
   :

 void someMethod(String id1, String id2) {
     Object lock;
     synchronized (lockMap) {
         lock = lockMap.get(id1+id2);
         if (lock == null) lockMap.put(id1+id2, (lock = new Object()));
     }
     synchronized (lock) {
         :
     }
 }

您需要对映射操作进行一点“全局”同步,或者可以使用一个并发实现。为了实现的简单性,我使用了基HashMap。

选择锁后,对其进行同步。

 类似资料:
  • 我可以检查对象中的值并基于此进行路由吗(就像写到不同的文件一样?)。我可以在pojo中添加注释以避免final json中的字段 我想到了将object转换为json,然后发送到Queue。然后我可以使用jsonpath进行条件路由。但是,我怎样才能从final JSON中省略一个字段呢?

  • 问题内容: 我的一位同事向我提出了一个有趣的问题,但是我找不到一个整洁漂亮的Java 8解决方案。问题是流式传输POJO列表,然后基于多个属性将它们收集在映射中- 映射导致POJO多次发生 想象以下POJO: 将其设置为: 备选方案1 :在“ stream”之外(或在之外)使用。 备选方案2 :创建地图项并流式传输,然后流式传输。海事组织,这有点太冗长,不太容易阅读。 备选方案3 :到目前为止,这

  • 我有一个关于Java并发性的问题。如果我基于一个对象同步一个临界区,那么将该变量声明为< code >final static对象与简单地声明为< code >最终对象有什么区别? 我知道 关键字将变量定义为属于该类,但我对它在多线程环境中的含义有点模糊。 请参阅下面的代码示例。目前,我将对象声明为,如果我添加keyword,会有什么不同? 谢谢你的帮助!

  • 在我的角度 this.device返回对象。每个对象都包含一个字段,并且在所有15个对象上都有不同的值。如果我可以访问underscore.js,我就会这样做,但是在这个项目中,我没有它。 什么是JS的方法来访问它而不需要执行for循环?

  • 问题内容: 我正在使用ObjectMapper(https://github.com/Hearst- DD/ObjectMapper )将JSON映射到Swift对象。 说我有这个JSON结构: 我有以下Swift对象: 如何使用JSON对象中的键区分映射和映射?非常感谢! 问题答案: 细节 Xcode 10.2.1(10E1001),Swift 5 json档案 ObjectMapper示例 检

  • 我想编写一个Java类,根据相关的时间戳计算一些规则(对于每个rueleId)的出现次数。 例如 输入: 输出: 我想我可以利用HashMap。 我认为这里的键是基于ruleId(type:String)和timestamp(type:Calendar)的,值是计数。 我怎样才能拥有基于两个不同对象的密钥?我的方法错了吗?