Will using the final parameter exclude the class for streaming security?

My tests show that the following code is not thread safe, although the class has no state and all the state shared between methods is passed as parameters from method to method. One instance of the following class is invoked by multiple threads.

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);
    }
}

The goal was to make this class thread safe because it is stateless, and all the state that needs to be shared between methods is passed from method to method as parameters. However, tests show that sometimes we get an exception with a null pointer on this line:

     if (limit != null && (aToken.getStart() >= limit.getStart())) {

It seems that once between checking a null value and calling getStart, the parameter constraint becomes zero.

, findFoo :

    Token findFoo(TokenIterator<? extends Token> iterator, Token start, 
                  final Token limit) {

, ? , , , Unsafe?

+3
4

, ? , , , Unsafe?

, , - .

final, limit TokenSearcher. , assessToken. - (, , ), , ( , ).

, findFoo .

, getStart .

+3

, getStart() Long Integer, null. un-boxing > =, .

+1

, - getStart .

. limit () , . , , , . , . , , , , , , .

( , , , searchForward TokenSearcher , .. . ?)

, - :

  • aStart null.
  • getStart() , null.

NPE .


?

. , searchForward.

, Limit ?

The code of an anonymous inner class refers to a copy limitstored as an instance variable of an object TokenSearcher. It is initialized when the and object is created final.

+1
source

As for your question in general, each method call really gets its own instance of the final parameter. The final does not create a static variable. It just allows you to set a variable only once.

0
source

All Articles