首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有效地锁定代码块以避免乐观锁异常

如何有效地锁定代码块以避免乐观锁异常
EN

Stack Overflow用户
提问于 2013-02-05 01:15:56
回答 2查看 1.1K关注 0票数 1

我对Java中的多线程不是很有经验。我想要的是为代码块设置一个锁。在我的例子中,我希望避免乐观锁异常,同时为某个用户执行一些同步。方法replicateUser可以由同一用户的多个线程调用。但不能保证,authenticatedUser总是相同的对象。

那么我如何有效地锁定这个部分呢?我不希望的是,该部分是锁定的所有线程,但只为那些具有相同的用户。我是否可以使用getUserName()在字符串对象上加锁,如下例所示?

代码语言:javascript
复制
private void replicateUser(AuthenticatedUser authenticatedUser) {
    //
    // How to synchronize the following block correctly?
    //
    synchronized (authenticatedUser.getUserName()) {
        User dbUser = userRepository.findOne(authenticatedUser.getUserName());
        if (!checkIsUserReplicated(authenticatedUser, dbUser)) {
            doReplication(dbUser);
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-02-05 01:45:58

你最好在authenticatedUser.getUserName ().intern ()上加锁,因为可以保证一旦两个字符串的内容相同,intern ()将为它们返回相同的对象。

此外,如果您的系统中保证只有一个具有特定用户名的AuthenticatedUser类实例,那么您可以直接锁定authenticatedUser

票数 1
EN

Stack Overflow用户

发布于 2013-02-05 02:44:57

正如您所提到的,在authenticatedUser.getUserName()上进行同步将不起作用,因为您可能有多个authenticatedUser实例。如果从不同的EntityManager上下文读取,两个线程读取相同的authenticatedUser数据将获得不同的实例。要解决此问题,您可以使用try/catch块包装doReplication方法,然后检查更改是否由另一个线程(使用em.refresh)进行,从而解决偶尔出现的乐观锁异常,也可以切换到使用悲观锁定,如下所述:http://wiki.eclipse.org/EclipseLink/Examples/JPA/Locking#Pessemistic_Locking http://wiki.eclipse.org/EclipseLink/Examples/JPA/PessimisticLocking

一旦锁定了authenticatedUser,您就可以检查它是否已被复制,然后释放锁或执行复制。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14691850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档