我在table > column
上存储了一个JSON对象。该JSON对象的示例是:
{
a :{
data: [1, 2, 3]
},
b :{
data: [4, 5, 6]
}
}
我有调度程序,用于在a.data (named scheduler A)
和b.data (named scheduler B)
上附加值。调度程序正在一种从table > column
获取JSON值并附加内容的方式。
问题:
此处scheduler A
和scheduler B
没有任何同步机制。因此,当scheduler A
和scheduler B
附加值事件同时发生时,scheduler A
的输出将被scheduler B
的输出覆盖,反之亦然。
处理同步的机制是什么?由于JSON值的行为将是动态的,因此我也无法在列上拆分JSON对象,因此必须使用该JSON格式。
答案 0 :(得分:1)
在最简单的情况下,您可以同步数据库访问(例如,有一个用于读取/写入数据库的专用对象,可以在调度程序中使用此对象来访问/修改json数据,并在调度程序中对此对象进行同步)。
类似这样的东西:
MockDB类
public class MockDB {
private JSONObject json;
public MockDB() {
this.json = fillJSON();
}
// fill JSON object with test data
private JSONObject fillJSON() {
JSONObject json = new JSONObject();
JSONObject map = new JSONObject();
map.put("data", Arrays.asList(1));
json.put("a", map);
map = new JSONObject();
map.put("data", Arrays.asList(11));
json.put("b", map);
return json;
}
public JSONObject getJSON() {
return cloneJson(json);
}
public void setJSON(JSONObject newJson) {
this.json = cloneJson(newJson);
}
// make a deep copy of JSON object
private JSONObject cloneJson(JSONObject jsonObj) {
JSONObject newJson = new JSONObject();
for(Object key : jsonObj.keySet()) {
if (jsonObj.get(key) instanceof JSONObject) {
newJson.put(key, cloneJson((JSONObject) jsonObj.get(key)));
} else if (jsonObj.get(key) instanceof JSONArray) {
newJson.put(key, ((JSONArray)jsonObj.get(key)).clone());
} else {
newJson.put(key, jsonObj.get(key));
}
}
return newJson;
}
}
字段更新程序类
public class ScheduledUpdater implements Runnable {
private final MockDB database;
private final String field;
public ScheduledUpdater(MockDB database, String field) {
this.database = database;
this.field = field;
}
@Override
public void run() {
// here we should synchronize on a whole DB access object
// as we need get & set to be atomic together
JSONObject json;
synchronized (database) {
json = database.getJSON();
JSONObject xData;
xData = (JSONObject) json.get(field);
Object obj = xData.get("data");
List<Integer> array = new ArrayList<>((List<Integer>) obj);
array.add(Collections.max(array) + 1); // add new item to json array
xData.put("data", array);
database.setJSON(json);
}
printValues(json);
}
private void printValues(JSONObject json) {
JSONObject ao = (JSONObject) json.get("a");
List<Integer> ad = (List<Integer>) ao.get("data");
JSONObject bo = (JSONObject) json.get("b");
List<Integer> bd = (List<Integer>) bo.get("data");
System.out.println(String.format("a: %02d; b: %02d", Collections.max(ad), Collections.max(bd)));
}
}
实际执行人
public static void main(String [] args) throws InterruptedException {
MockDB database = new MockDB();
System.out.println("starting tasks\n");
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(new ScheduledUpdater(database, "a"), 0, 1, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(new ScheduledUpdater(database, "b"), 0, 1, TimeUnit.SECONDS);
// run test for 5 seconds
executor.awaitTermination(5, TimeUnit.SECONDS);
executor.shutdown();
// let all threads to stop
Thread.sleep(250);
System.out.println("\ntasks stopped; json: " + database.getJSON());
}
PS:此外,您还可以从java.util.concurrent包中检查同步原语。