Mark
Mark

Reputation: 1799

Synchronized Get Methods in Java

This may seem like pedantry but is really me questioning my fundamental assumptions.. :)

In the java documentation on synchronised methods, there is the following example:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

Is the synchronized keyword really required on the value method? Surely this is atomic and whether the value is retrieved before or after any calls to related methods on other threads makes little difference? Would the following suffice:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public int value() {
        return c;
    }
}

I understand that in a more complex case, where multiple private variables were being accessed then yes, it would be essential - but in this simple case, is it safe to assume that this can be simplified?

Also, I suppose that there is a risk that future modifications may require the value method to be synchronised and this could be forgotten, leading to bugs, etc, so perhaps this counts somewhat as defensive programming, but I am ignoring that aspect here.. :)

Upvotes: 2

Views: 990

Answers (2)

Manos Nikolaidis
Manos Nikolaidis

Reputation: 22254

synchronized is required for both reading and writing a variable from another thread. This guarantees

  1. that values will be copied from cache or registers to RAM (granted this is important for writing not reading)

  2. it establishes that writes will happen before reads if they appear so in code. Otherwise the compiler is free to rearrange lines of bytecode for optimization

Check Effective Java Item 66 for a more detailed analysis

Upvotes: 2

dkatzel
dkatzel

Reputation: 31648

Yes, synchronized is really required on value(). Otherwise a thread can call value() and get a stale answer.

Surely this is atomic

For ints I believe so, but if value was a long or double, it's not. It is even possible to see only some of the bits in the field updated!

value is retrieved before or after any calls to related methods on other threads makes little difference?

Depends on your use case. Often it does matter.

Some static analysis software such as FindBugs will flag this code as not having correct synchronization if value() isn't also synchronized.

Upvotes: 6

Related Questions