0

For the following class, what are the implications of making mNumSides final? Is "thread-safety" affected?

class Shape {
    private int mNumSides;

    public Shape(int numSides) {
        mNumSides = numSides;
    }

    public int getNumSides() {
        return mNumSides;
    }
}
Matthew
  • 6,356
  • 9
  • 47
  • 59

2 Answers2

3

Absolutely. final keyword guarantees that all the threads see the same value of mNumSides at all the times. More information on final and its impact on the Memory Model here.

Without using final the object might be inconsistently published to other threads, and there is probability (extremely low though) that a thread might see the value of mNumSides as 0 rather than numSides as passed in constructor. Making it volatile or static will also work though.

Jatin
  • 31,116
  • 15
  • 98
  • 163
  • 2
    As does the `volatile` keyword. – William Morrison Jul 12 '13 at 20:00
  • 2
    However, the `final` keyword does not make a class magically thread-safe. It means that the reference pointer of that variable cannot change, it doesn't mean that the contents of the object it points to cannot change. This is *very* important to note in a multi-threaded environment. – Colin M Jul 12 '13 at 20:03
  • 1
    @ColinMorelli Great point! However in this case its fine as primitives have no internal data. – William Morrison Jul 12 '13 at 20:06
  • @WilliamMorrison That's correct, primitives store no internal state, and all object-implementations (`String`, `Integer`, `Float`, etc) are immutable by design. – Colin M Jul 12 '13 at 20:08
  • So to clarify, suppose in one thread I create a global `Shape` object `Shape SHAPE = new Shape(4);`. In the current implementation, there is a risk of other threads calling `SHAPE.getNumSides` and seeing `0` rather than `4`, whereas if I made `mNumSides` final or volatile it would guarantee that other threads see `4`? – Matthew Jul 15 '13 at 05:50
0

Num sides cannot be reassigned if it is declared as final. There'd be no risk of multiple threads reading different values due to it not being declared as volatile.

So, declaring the variable as final makes the class thread safe. As of now its not thread safe.

Declaring an object final keeps its reference from being reassigned, however if the object had internal data, that data could be reassigned which would not be thread-safe. This is an important point made by Colin on another answer.

In this case the data is a primitive, and so has no internal data. So here, declaring it final works fine.

William Morrison
  • 10,953
  • 2
  • 31
  • 48