【发布时间】:2021-03-20 12:46:38
【问题描述】:
我想根据输入参数同步一个方法或一个块。
所以我有一个 API,它在后有效负载中具有两个长类型(可以是原始或包装)输入(比如说 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 Controller 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;
}
}
【问题讨论】:
-
您在地图上和锁定对象上同步。看看你的同步块的范围与我的比较。
标签: java multithreading spring-boot synchronization thread-safety