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

How should the synchronization be used in case of strings?

我在数据库中有一个学生 table,其中包含姓名、主题和标记字段。 table.

中,1 个学生可以有多个不同科目的记录

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

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);

    }

}

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

This method can be called by multiple threads simultaneously for same student name and subject.

实现此目的的一种方法是在您的数据库上创建一个唯一限制,如果数据库已经具有 student-name/subject 组合,该限制将引发异常。所以你会:

  1. 查询 student-name/subject
  2. 如果不存在,尝试将其插入数据库
  3. 如果失败,则再次执行查询以防止竞争条件。
  4. 如果仍然不存在则抛出数据库异常

可以通过同步来做到这一点,尽管这很重要。你可以这样做:

  1. 创建一个包装 student-name/subject 的对象,其中 hashcode()equals() 使用这些字段。
  2. 无论何时去做手术,都使用 ConcurrentHashMapputIfAbsent(...) 您的 StudentNameSubject。该值可以只是一些随机常量对象,因为您不能使用 null 并且没有 ConcurrentHashSet.
  3. 然后在您创建的 StudentNameSubject 或地图中的地图(如果已经存在)上同步。
  4. synchronized 块内执行数据库操作。
  5. 您可以在完成 synchronized 块后从地图中删除条目。