在字符串的情况下应该如何使用同步?
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 组合,该限制将引发异常。所以你会:
- 查询 student-name/subject
- 如果不存在,尝试将其插入数据库
- 如果失败,则再次执行查询以防止竞争条件。
- 如果仍然不存在则抛出数据库异常
您可以通过同步来做到这一点,尽管这很重要。你可以这样做:
- 创建一个包装 student-name/subject 的对象,其中
hashcode()
和 equals()
使用这些字段。
- 无论何时去做手术,都使用
ConcurrentHashMap
和 putIfAbsent(...)
您的 StudentNameSubject
。该值可以只是一些随机常量对象,因为您不能使用 null
并且没有 ConcurrentHashSet
.
- 然后在您创建的
StudentNameSubject
或地图中的地图(如果已经存在)上同步。
- 在
synchronized
块内执行数据库操作。
- 您可以在完成
synchronized
块后从地图中删除条目。
我在数据库中有一个学生 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 组合,该限制将引发异常。所以你会:
- 查询 student-name/subject
- 如果不存在,尝试将其插入数据库
- 如果失败,则再次执行查询以防止竞争条件。
- 如果仍然不存在则抛出数据库异常
您可以通过同步来做到这一点,尽管这很重要。你可以这样做:
- 创建一个包装 student-name/subject 的对象,其中
hashcode()
和equals()
使用这些字段。 - 无论何时去做手术,都使用
ConcurrentHashMap
和putIfAbsent(...)
您的StudentNameSubject
。该值可以只是一些随机常量对象,因为您不能使用null
并且没有ConcurrentHashSet
. - 然后在您创建的
StudentNameSubject
或地图中的地图(如果已经存在)上同步。 - 在
synchronized
块内执行数据库操作。 - 您可以在完成
synchronized
块后从地图中删除条目。