我在return语句中通过以下方法获得了此违规行为:
protected Token getAccessToken() {
synchronized (this) {
if (token == null || isExpired(token))
token = createToken();
}
return token; // <-- Inconsistent synchronization of blablabla.token; locked 75% of time
}
是否存在与token
字段相关的可见性问题?据我所知,synchronized
块令牌后应该有最新的值。
我错过了什么或是假阳性吗?
答案 0 :(得分:4)
请考虑以下事项:
如果你想做你正在做的事情,那么token
可能需要是易变的(但这可能不是一个充分的保证!),或者你应该总是从synchronized块中返回值,或者分配token
的值为synchronized块内的局部变量,并从外部返回该局部变量。
在此期间,这甚至没有考虑其他方法可能正在做什么。如果另一个(同步或非同步)方法也修改了token
(例如,指定null
),那么您可能会因为假设 token
而更糟糕not null(正如您刚刚检查过的那样),而实际上它可能是null
现在。
答案 1 :(得分:3)
线程A可能会返回刚刚由线程B重新创建的令牌,因为令牌已过期。
因此,线程B将从同步块中写入令牌,但线程B将从未同步的块中读取它。所以是的,可能会有问题。返回应该在同步块内。