gzuniga
gzuniga

Reputation: 23

Thread-safe HashMap of Objects with Nested ArrayList

I have a HashMap of objects with nested ArrayLists that is accessed by multiple threads.

I am wondering if declaring it as a synchronized HashMap is enough to make it thread-safe.

public class ExampleRepository {

    private static Map<String, Example> examples = Collections.synchronizedMap(new HashMap<>());

    public static void addExample(Example example) {
        examples.put(example.getKey(), example);
    }

    public static Example getExample(String key) {
        return examples.get(key);
    }

}
public class Example {

    private String key;
    // More attributes
    private List<AnotherObject> anotherObjectList = new ArrayList<>();

    // Constructor

    public List<AnotherObject> getAnotherObjectList() {
        return anotherObjectList;
    }

    // More getters & Setters

}
public class Doer {

    // This function runs in an ExecutorService with many threads
    public static one(String key) {
        Example example = ExampleRepository.getExample(key);
        if (example != null) {
            // Do stuff
            example = new Example(values);
            AnotherObject anotherObject = new AnotherObject(values);
            example.getAnotherObjectList().add(anotherObject);
            ExampleRepository.addExample(example);
        }
        two(example);
    }

    private static two(Example example) {
        // Do stuff
        AnotherObject anotherObject = new AnotherObject(values);
        trim(example.getAnotherObjectList(), time);
        example.getAnotherObjectList().add(anotherObject);
    }

     private static void trim(List<AnotherObject> anotherObjectList, int time) {
        short counter = 0;
        for (AnotherObject anotherObject : anotherObjectList) {
            if (anotherObject.getTime() < time - ONE_HOUR) {
                counter++;
            } else {
                break;
            }
        }
        if (counter > 0) {
            anotherObjectList.subList(0, counter).clear();
        }
    }

}

I guess the question is adding Example objects to the HashMap thread safe? Also, is removing and adding AnotherObject objects to the nested list thread-safe or should I declared it as synchronized ArrayList?

I would greatly appreciate any insights. Thank you very much!

Thank you very much for the answers. I just realized that I actually loop a little over the nested AnotherObject. If i make the ArrayList a synchronized ArrayList, should I still put it in a synchronized block?

Thank you again!

Upvotes: 0

Views: 368

Answers (2)

Amit Bera
Amit Bera

Reputation: 7325

I guess the question is adding Example objects to the HashMap thread safe?

-> Yes putting Example object to map is thread-safe.

Also, is removing and adding AnotherObjet objects to the nested list thread-safe or should I declared it as synchronized ArrayList?

-> Removing objects from the list does not guarantee that it will be thread-safe.

Any operation on the map will be thread-safe as you have used the Synchronized map. ArrayList in Example object will be still unsafe to thread.

Thread-safe in a collection/map does not mean it will make API of any/every object it contains thread-safe.

Upvotes: 0

Andy Turner
Andy Turner

Reputation: 140484

The thing you have to be clear about is what you mean by "thread safe".

I guess the question is adding Example objects to the HashMap thread safe?

Making the map synchronized guarantees that the structural modifications you make to the map are visible to all threads.

Also, is removing and adding AnotherObjet objects to the nested list thread-safe or should I declared it as synchronized ArrayList?

No: you would need to externally synchronize accesses to the lists if you want structural modifications to the lists to be visible in all threads.

That could mean using synchronizedList, but you could "manually" synchronize on the list, or even on the map (or one of a number of other ways that create happens-before guarantees).

Upvotes: 0

Related Questions