【发布时间】:2016-08-19 07:45:53
【问题描述】:
我在多线程环境中更新一个值
Class TestClass{
public static TestObject updateTestObject (TestObject testObject )
{
testObject.setLatestSequence (testObject.getLatestSequence () + 1);
return testObject ;
}
}
该值用于另一个类似的类中。该函数是同步的,因此一次只能有一个线程进入。
Class parentClass
{
void synchronized updateDBSequence()
{
// Read old value from DB
TestObject testObject = readFromDAO.readTestClass(naturalKey);
// Access in static manner, Issue ? If two threads go in, the object
//the return will have duplicate sequence number in it e.g. first read
//1 as latest sequence second also read 1 and both updated it to 2 and save in DB.
TestClass.updateTestObject (testObject);
// DAO has already been injected by spring
// Update value in DB
testObjectDAO.update (testObject);
}
在多线程环境中运行时,有时从 testClass.updateTestObject() 方法返回的对象有重复序列,因此重复序列保存在 DB 中。我们希望它们始终是独一无二的
为了克服这个问题,函数 updateDBSequence () 已经同步,但没有解决问题,然后意识到 TestClass.updateTestObject () 函数可能导致问题,因为它是静态的并且线程在其中将不知道其他线程用什么更新了该值。
所以为了解决这个问题,Class.function 方式的访问被更改为其中的实际代码,而不是在代码中调用具有类名的静态函数。
void synchronized updateDBSequence()
{
// Read old value from DB
TestObject testObject = readFromDAO.readTestClass(naturalKey);
// DO not access in static manner
testObject.setLatestSequence (testObject.getLatestSequence () + 1);
// DAO has already been injected by spring
// Update value in DB
testObjectDAO.update (testObject);
}
它会解决问题吗?进入静态方法的线程是否不知道其他线程更新的值是什么,即他们正在处理的对象是共享的,并且每个都有自己的副本。
【问题讨论】:
-
使用真实的数据库序列。
-
但是在这种情况下线程的行为呢?
-
void synchronized function updateDBSequence()?那不是 Java。 -
无法判断。太多的未知数。 DAO 做什么。什么是自然键?什么是 parentClass 以及它们有多少个实例。事务在哪里,等等。但是尝试通过线程同步来解决事务问题并不是正确的方法。如果您需要全局递增序列,请使用数据库序列,这就是它的用途。但是阅读你所有的问题和伪代码,我很难理解你想要实现的目标。
-
总是使用 newInstance 调用父类
标签: java multithreading concurrency synchronization