2
Class A {
    private Map<Oject,Object> map;
    public void clear() {
        map.clear();
    }

    public void work() {
        synchronized (map) {
            map.put(new Object, new Object();
        }
    }
}

If thread A is in the middle of the work() method, does this mean thread B won't block if executing the clear() method?

What is the difference between the code above and having this?

    public void clear() {
        synchronized (map) {
            map.clear();
        }
    }
Roman C
  • 49,761
  • 33
  • 66
  • 176
mvd
  • 2,596
  • 2
  • 33
  • 47

3 Answers3

5

Your suspicion is correct; this code has a bug.

You need to lock around clear() as well; otherwise; you can still end up running put() and clear() concurrently.

However, you should actually use a ConcurrentHashMap() instead.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • or Collections.synchronizedMap ) – Leonidos Jan 10 '13 at 21:35
  • @SLaks I feel what he is looking for is Collections.synchronizedMap. because he want s to lock the map if one thread is doing put(..). with Concur..Map, clear() and put() from different threads could go at same time. correct me please if my understanding was wrong. – Kent Jan 10 '13 at 21:40
  • Does using a ConcurrentHashMap mean it's safe to remove synchronized blocks? Specifically in relation to retrivals/insertions overlapping with clear. – mvd Jan 10 '13 at 21:47
  • Yes, it is safe to remove `synchronized` blocks from a `ConcurrentHashMap`. – Louis Wasserman Jan 10 '13 at 21:58
  • @Kent: `Collections.synchronizedMap()` is useless. http://stackoverflow.com/a/14148963/34397 – SLaks Jan 11 '13 at 16:46
1

Correct. Why would it? That's the point of the synchronized block - and thread B hasn't executed a synchronized block. In this case, it's exactly like there was no synchronisation at all.

dty
  • 18,795
  • 6
  • 56
  • 82
0

For each location in which access to the given resource should be controlled you should synchronize. Your first example will only run in a synchronized manner if it hits a synchronized block (which it doesn't in clear()), otherwise it'll continue as normal. Your lock around clear() in the second example will cause thread B to check.

digitaljoel
  • 26,265
  • 15
  • 89
  • 115