Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you ensure multiple threads can safely access a class field?

When a class field is accessed via a getter method by multiple threads, how do you maintain thread safety? Is the synchronized keyword sufficient?

Is this safe:

public class SomeClass {
    private int val;

    public synchronized int getVal() {
        return val;
    }

    private void setVal(int val) {
        this.val = val;
    }
}

or does the setter introduce further complications?

like image 208
Chris Carruthers Avatar asked Sep 23 '08 00:09

Chris Carruthers


1 Answers

If you use 'synchronized' on the setter here too, this code is threadsafe. However it may not be sufficiently granular; if you have 20 getters and setters and they're all synchronized, you may be creating a synchronization bottleneck.

In this specific instance, with a single int variable, then eliminating the 'synchronized' and marking the int field 'volatile' will also ensure visibility (each thread will see the latest value of 'val' when calling the getter) but it may not be synchronized enough for your needs. For example, expecting

 int old = someThing.getVal();
 if (old == 1) {
    someThing.setVal(2);
 }

to set val to 2 if and only if it's already 1 is incorrect. For this you need an external lock, or some atomic compare-and-set method.

I strongly suggest you read Java Concurrency In Practice by Brian Goetz et al, it has the best coverage of Java's concurrency constructs.

like image 150
Cowan Avatar answered Sep 26 '22 18:09

Cowan