我的測試表明,即使該類是無狀態的,並且方法之間共享的所有狀態都作爲方法的參數傳遞給方法,但下面的代碼不是線程安全的。多個線程正在調用以下類的單個實例。最終參數的使用是否會阻止類成爲線程安全的?
public class ThingFinder {
Token findFoo(TokenIterator<? extends Token> iterator,
Token start, final Token limit) {
Token partOfFoo = searchForward(iterator, start, new TokenSearcher() {
int maxTokens = 5;
@Override
public SearchAction assessToken(Token aToken) {
if (limit != null && (aToken.getStart() >= limit.getStart())) {
return SearchAction.STOP;
}
if (maxTokens-- == 0) {
return SearchAction.STOP;
}
if (isAThing(aToken)) {
return SearchAction.MATCH;
} else {
return SearchAction.IGNORE;
}
}
});
return partOfFoo;
}
public Token extractAThing(TokenIterator<? extends Token> iterator) {
Token start = findStart(iterator);
Token limit = findLimit(iterator, start);
return findFoo(iterator, start, limit);
}
}
這樣做的目的是爲這個類是線程安全的,由於是無狀態的事實,這需要傳遞從方法到方法參數的方法之間共享所有的狀態。然而,測試表明,有時候我們在這條線得到一個空指針異常:
if (limit != null && (aToken.getStart() >= limit.getStart())) {
看來,有時空值檢查和getStart的調用的參數限制變得無效。
注意,方法findFoo聲明限制參數是最終:
Token findFoo(TokenIterator<? extends Token> iterator, Token start,
final Token limit) {
難道最終方法參數不堆棧幀的情況下,而是一個實例的方法的所有調用之間共享?如果確實在所有調用中共享一個實例,那麼這是否意味着使用最終參數會使類本質上處於不安全狀態?
您確定限制爲空嗎?如果aToken爲null,則會得到相同的異常。 – MikeTheReader 2011-05-26 22:42:10
你有多確定「極限」是罪魁禍首,而不是「aToken」? – 2011-05-26 22:43:18
aToken保證不爲空。從框架中可以清楚地看到回叫但很難在帖子中顯示。另外,我在測試期間爲aToken添加了空指針檢查。 – ditkin 2011-05-26 22:45:02