繁体   English   中英

使方法同步将确保它是线程安全的吗?

[英]Is making a method synchronized will ensure that it is thread safe?

我有一种方法,其中一些数据库插入操作正在使用休眠进行,我希望它们是线程安全的。 该方法以参数为单位获取某些数据,并且有可能有时在同一时间点使用相同数据进行两次调用。

由于性能下降,我无法锁定这些表。 谁能建议使该方法成为同步方法可以解决问题?

同步方法将确保一次只能由一个线程访问该方法。 如果此方法是您写入数据库的唯一方法,那么可以,这将阻止两个线程同时写入。 但是,您仍然必须处理这样一个事实,即您需要对同一数据执行多个插入操作。

您应该让Hibernate处理并发,这就是要做的事情。 不要以为Hibernate会锁定任何东西:为此,它支持乐观事务 从以上链接引用:

与高并发性和高可伸缩性一致的唯一方法是通过版本控制进行乐观并发控制。 版本检查使用版本号或时间戳来检测冲突的更新并防止更新丢失。 Hibernate提供了三种使用乐观并发编写应用程序代码的方法。

数据库并发由事务处理。 事务具有“原子一致性持久隔离(ACID)”属性。 它们提供了并发访问数据库的程序之间的隔离。 在spring框架的Hibernate DAO模板中,有用于数据库上CRUD操作的单行方法。 单独使用时,不需要按方法进行同步。 如果您需要使用特定的传播设置,rollbackFor设置,隔离设置将“您的方法”声明为事务性的,则Spring提供了声明式(XML),程序化和注释元数据驱动的事务管理。 因此,在“您的方法”中,您可以进行多次保存,更新,删除等操作,并且ORM将确保使用您在元数据中给定的事务设置执行该操作。

另一个问题是线程必须锁定参与事务的所有对象,否则事务可能会失败或ORM将保留陈旧数据。 在另一种情况下,由于锁定顺序,可能导致死锁。 我认为这才是真正回答您问题的方法。

对象a和b都有一个Lock类型的实例变量。 布尔标志可用于指示交易成功。 如果客户端代码失败,则可以重试同一事务。

             if (a.lock.tryLock()) {
                try {
                    if (b.lock.tryLock()) {
                        try {
                            // persist or update object a and b
                        } finally {
                            b.lock.unlock();
                        }
                    }
                } finally {
                    a.lock.unlock();
                }
            }

使用同步方法的问题在于,它锁定了整个Service或DAO类,从而使其他线程无法使用其他服务方法。 通过对对象使用单独的锁,我们可以获得细粒度并发的优势。

不可以。此方法可能使用其他方法和对象,这些方法和对象可能不是线程安全的。 synchronized使线程一次只能使用该方法的对象monitor一次,因此它使线程安全的方法相对于该对象。

如果确定所有其他线程仅通过此方法使用共享功能,则使其synchronized可能就足够了。

选择最佳策略取决于体系结构,有时使用方法同步之类的技巧来提高性能似乎更容易,但这是不好的方法。

毫无疑问,您应该使用事务,并且如果使用该策略遇到性能问题,则应该优化数据库查询或数据库结构。

请记住,“同步”应尽可能地原子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM