0

Since the objects we share in flyweight design pattern are immutable, I'm wondering if we need to take synchronization into consideration? Even when multiple threads try to access the same objects and insert into the shared pool since the objects are always the same, I think we do not need to synchronize, please shed some lights on this. Thanks

public class WeakPool<T> {
    private final WeakHashMap<T, WeakReference<T>> pool = new WeakHashMap<T, WeakReference<T>>();
    public T get(T object) {
        final T res;
        WeakReference<T> ref = pool.get(object);
        if (ref != null) {
            res = ref.get();
        } else {
            res = null;
        }
        return res;
    }
    public void put(T object) {
        pool.put(object, new WeakReference<T>(object));
    }
}
public class InternPool<T> {

    private final WeakPool<T> pool = new WeakPool<T>();

    public synchronized T intern(T object) {
        T res = pool.get(object);
        if (res == null) {
            pool.put(object);
            res = object;
        }
        return res;
    }
}

Here is the code from this post: Generic InternPool<T> in Java?

The question is do we need synchronized on this intern method?

Yiwei
  • 89
  • 8

1 Answers1

0

Most multithreaded instances of the flyweight pattern require synchronization when shared components are constructed, acquired, or released, even if the flyweight objects themselves are immutable. It depends on the specific data structures involved.

Synchronization requirements are usually determined by implementation details, not design patterns. They should be hidden behind appropriate interfaces.

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
  • Can you elaborate on why immutable components would require synchronization? – jaco0646 Apr 16 '19 at 00:07
  • The immutable components themselves don't require synchronization, but in order to share them you usually have to look them up in some sort of collection, to which other threads may be adding new ones, and that collection would require synchronization. – Matt Timmermans Apr 16 '19 at 02:12
  • For example, I have a map here Map, if the map contains a specific MyObject before, then it will return the same MyObject, do we need synchronization here? I'm thinking when even when multiple threads try to insert into the map, since MyObject is immutable its guaranteed to be the same, so for this purpose do we still need synchronization? Thanks – Yiwei Apr 16 '19 at 12:23
  • Can you please see the detailed code in the question? I cannot see why we need synchronized on the intern method. – Yiwei Apr 16 '19 at 13:03
  • It's simply because putting stuff in a map involves manipulations to the internal map data structure that can get messed up if another thread is trying to do the same thing at the same time. I don't know why you would think that having immutable keys and values somehow transfers any thread safety magic to the map itself. – Matt Timmermans Apr 16 '19 at 13:15
  • Oh, I thought weakhashmap internally uses concurrenthashmap. So if we use concurrenthashmap here, then we don't need synchrondized keyword, am I correct? – Yiwei Apr 16 '19 at 18:39
  • If you use concurrenthashmap then you will have a level 2 concurrency problem -- 2 threads that put at the same time may return different objects for the same key (you can use computeIfAbsent to fix that). Also you will break the GC behaviour that WeakHashMap provides. – Matt Timmermans Apr 16 '19 at 19:06