首页 \ 问答 \ 如何在字符串的情况下使用同步?(How should the synchronization be used in case of strings?)

如何在字符串的情况下使用同步?(How should the synchronization be used in case of strings?)

我在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上进行同步,因为我只想在同一记录更新的情况下进行同步。 最好的方法是什么?


I have a student table in DB which has name, subject and marks fields in it. 1 student can have multiple records for different subjects in this table.

I have a student DAO class which has an update method like this:

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

    }

}

This method can be called by multiple threads simultaneously for same student name and subject. I want to make it synchronized only in case of multiple threads updating same name and subject. So I thought on synchronizing this method on string of name+subject but as this is a bad practice also not giving me guranteed results due to string constant pool (presence of that string in it), I want to use some better solution. I don't want to synchronize on DAO.class as I want synchronization only in case of same records update. What should be the best way to do this?


原文:https://stackoverflow.com/questions/37560026
更新时间:2019-12-13 07:37

最满意答案

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

一种方法是在数据库上创建一个唯一的限制,如果数据库已经有学生名/主题组合,则会引发异常。 所以你会:

  1. 查询学生姓名/科目
  2. 如果它不存在,请尝试将其插入数据库中
  3. 如果失败则再次执行查询以防止竞争条件。
  4. 如果它仍然不存在则抛出数据库异常

可以使用同步执行此操作,尽管这不是一件容易的事。 你可以这样做:

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

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

One way to do this would be to create a unique restriction on your database that will throw an exception if the database already has the student-name/subject combination. So you would:

  1. query for the student-name/subject
  2. if it didn't exist, try to insert it in the database
  3. if that fails then do the query again to protect against the race condition.
  4. if it still doesn't exist then throw the database exception

You could do this with synchronization although it is non trivial. You could do something like:

  1. Create a object that wraps the student-name/subject where the hashcode() and equals() use those fields.
  2. Use a ConcurrentHashMap and putIfAbsent(...) your StudentNameSubject whenever you go to do your operation. The value can just be some random constant object since you can't use null and there is no ConcurrentHashSet.
  3. Synchronize then on either the StudentNameSubject you created or the one from the map if it already exists.
  4. Do your database operations inside the synchronized block.
  5. You can delete the entry from the map after you complete the synchronized block.
2016-06-09

相关问答

更多

如何在Java中创建图像(How to create image in Java)

背景在图像中是黑色的,因为除了矩形中的值之外,您没有给任何像素值。 BufferedImage开始时每个像素的RGB为(0,0,0),这是黑色的。 要为整个图像提供白色背景,只需用白色填充整个图像即图像。 BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); g = image.createGraphics(); // not sure on this line, but this seem

如何减少android SQLite中的自动增量_id?(How to decrease the Auto increment _id in android SQLite?)

编辑:也许我应该说清楚只是插入具有正确id的行而不是操纵序列号肯定比下面的方法更好。 如果表中没有id = 3的行,则即使在AUTOINCREMENT表中也可以在id中插入固定值。 也就是说,如果您确定 ,可以使用自动增量值设置为任意值; UPDATE sqlite_sequence set seq=<next sequence no -1> where name=<table name>; 也就是说,如果你想在表'TableA'上的下一个插入中使用AUTOINCREMENT来生成5,那么你可

JSON Jquery For Loop(JSON Jquery For Loop)

假设你有这个HTML <ul id="navigation"></ul> 你的JS应该像:: var Obj = { "alsotaking":[ ["bla","Software Engineering",1], ["bla","Mobile Applications",11], ["bla","Practical Networks",71], ["bla","Digital Forensics",53] ] }; function readObjA

脚本拼图

最新问答

更多
  • NumPy标量,广播和__iadd__方法(NumPy scalars, broadcasting and the __iadd__ method)
  • 快速排序算法输出错误(Getting wrong output for quicksort algorithm)
  • Rails管理员:没有Rails 4应用程序的编辑,显示或删除按钮(Rails Admin: No edit, show, or delete buttons for Rails 4 app)
  • 部分刷新问题触发两次(Issue with partial refresh triggered twice)
  • jsPlumb draggable element javascript函数(jsPlumb draggable element javascript function)
  • MVC4:ViewModel(带有radiobuttonlist)在HttpPost之后为空(MVC4: ViewModel (with radiobuttonlist) is empty after HttpPost)
  • 如何在同一帐户上设置“Dev repo”(在prod和团队之间)(How to set up a “Dev repo” (between the prod and the team) on the same account)
  • 如何在tcl中将eth0配置为发送方udp端口(how to configure eth0 as a sender udp port in tcl)
  • EF6.1 beta 1如何获得Tooling Consolidation功能?(EF6.1 beta 1 how to get the Tooling Consolidation feature?)
  • 适用于Windows和PHP 5.5的Phalcon(Phalcon for Windows and PHP 5.5)
  • 有没有办法忽略hg责任中的提交?(Is there a way to ignore a commit in hg blame?)
  • Desire2通过API学习访问学期的权限(Desire2Learn Permissions to Access Semesters Via API)
  • 从aspx将服务器的文件复制到另一台服务器(Copy a file of a server to another server from aspx)
  • 使用YSlow / Web Developer扩展程序确定页面大小(Figuring out page size with YSlow / Web Developer extension)
  • Select语句将字符串中的前7个字符与其他表中的其他7个字符进行比较(Select statement which compares first 7 chars in a string with other 7 chars in other table)
  • 检测对注册表的更改,防止更改等(Detect changes to registry, prevent changes, etc)
  • 用户的鼠标/键盘运动分析是否有特殊名称?(Does the analysis of mouse/keyboard motions of a user have a special name?)
  • 获取Rails中资源的路由列表(Get list of routes for a resource in Rails)
  • 用函数值除以数字(Divide a function value by a number)
  • 熊猫Python:如何从今天开始创建失效列?(Pandas Python: How to create lapse since today column?)
  • GDK Bug报告(GDK Bug Reports)
  • 困惑于在python中循环遍历列表(confused about looping through lists in python)
  • 'less'由'which'输出指定的文件('less' the file specified by the output of 'which')
  • 如何在ASP.NET中优化AJAX(How to optimize AJAX in ASP.NET)
  • 在文本文件中转换纪元时间(Convert epoch times in text file)
  • 表细胞伸展(Table cell stretching)
  • GridView控件(GridView Control)
  • 从构建定义文件控制pdb文件输出(Control pdb file output from build defintion file)
  • *将方法传递给类(*Passing a Method into a Class)
  • 如何在HttpReceiveHttpRequest()中使用HTTPS?(How to use HTTPS with HttpReceiveHttpRequest()?)