如何在字符串的情况下使用同步?

时间:2016-06-01 05:21:13

标签: java multithreading synchronized

我在DB中有一个学生表,其中包含名称,主题和标记字段。 1名学生可以在此表中为不同科目创建多个记录。

我有一个学生DAO课程,它有一个像这样的更新方法:

public marks updateStudent(String name, String subject, int marks){
//this method first check if the record of this name and subject is there in DB
    if(getStudentRecordFromDB(name, subject){
        //then return marks for this student

    }else{
        //insert the record in DB and return marks
        insertRecord(name, subject, marks);

    }

}

同一个学生姓名和科目可以同时为多个线程调用此方法。我想仅在多个线程更新相同名称和主题的情况下使其同步。 所以我想在名字+主题的字符串上同步这个方法但是因为这是一个不好的做法也没有给我保证结果由于字符串常量池(在其中存在该字符串),我想使用一些更好的解决方案。 我不想在DAO.class上进行同步,因为我只想在同一记录更新的情况下进行同步。 最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

  

同一个学生姓名和科目可以同时为多个线程调用此方法。

执行此操作的一种方法是在数据库上创建一个唯一限制,如果数据库已具有student-name / subject组合,则会引发异常。所以你会:

  1. 查询学生姓名/主题
  2. 如果它不存在,请尝试将其插入数据库
  3. 如果失败,则再次执行查询以防止竞争条件。
  4. 如果它仍然不存在则抛出数据库异常
  5. 可以使用同步执行此操作,尽管这不是一件容易的事。你可以这样做:

    1. 创建一个对象,该对象包含hashcode()equals()使用这些字段的学生姓名/主题。
    2. 每当您开始手术时,请使用ConcurrentHashMapputIfAbsent(...) StudentNameSubject null。该值可以只是一些随机常量对象,因为您无法使用ConcurrentHashSet且没有StudentNameSubject
    3. 然后同步您创建的synchronized或地图中的synchronized(如果已存在)。
    4. private String getJson(final Bundle bundle) { if (bundle == null) return null; JSONObject jsonObject = new JSONObject(); for (String key : bundle.keySet()) { Object obj = bundle.get(key); try { jsonObject.put(key, wrap(bundle.get(key))); } catch (JSONException e) { e.printStackTrace(); } } return jsonObject.toString(); } public static Object wrap(Object o) { if (o == null) { return JSONObject.NULL; } if (o instanceof JSONArray || o instanceof JSONObject) { return o; } if (o.equals(JSONObject.NULL)) { return o; } try { if (o instanceof Collection) { return new JSONArray((Collection) o); } else if (o.getClass().isArray()) { return toJSONArray(o); } if (o instanceof Map) { return new JSONObject((Map) o); } if (o instanceof Boolean || o instanceof Byte || o instanceof Character || o instanceof Double || o instanceof Float || o instanceof Integer || o instanceof Long || o instanceof Short || o instanceof String) { return o; } if (o.getClass().getPackage().getName().startsWith("java.")) { return o.toString(); } } catch (Exception ignored) { } return null; } public static JSONArray toJSONArray(Object array) throws JSONException { JSONArray result = new JSONArray(); if (!array.getClass().isArray()) { throw new JSONException("Not a primitive array: " + array.getClass()); } final int length = Array.getLength(array); for (int i = 0; i < length; ++i) { result.put(wrap(Array.get(array, i))); } return result; } 块内进行数据库操作。
    5. 完成NSManagedObject阻止后,您可以从地图中删除该条目。