我对Java中的多线程不是很有经验。我想要的是为代码块设置一个锁。在我的例子中,我希望避免乐观锁异常,同时为某个用户执行一些同步。方法replicateUser可以由同一用户的多个线程调用。但不能保证,authenticatedUser总是相同的对象。
那么我如何有效地锁定这个部分呢?我不希望的是,该部分是锁定的所有线程,但只为那些具有相同的用户。我是否可以使用getUserName()在字符串对象上加锁,如下例所示?
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);
}
}
}发布于 2013-02-05 01:45:58
你最好在authenticatedUser.getUserName ().intern ()上加锁,因为可以保证一旦两个字符串的内容相同,intern ()将为它们返回相同的对象。
此外,如果您的系统中保证只有一个具有特定用户名的AuthenticatedUser类实例,那么您可以直接锁定authenticatedUser。
发布于 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,您就可以检查它是否已被复制,然后释放锁或执行复制。
https://stackoverflow.com/questions/14691850
复制相似问题