Collections.synchronizedMap - worth using?

Discussion in 'Java' started by Ian Pilcher, Jan 30, 2007.

  1. Ian Pilcher

    Ian Pilcher Guest

    I've got a map that will be access by multiple threads, so I'm
    considering using Collections.synchronizedMap to "wrap" it. There will
    be occasions, though, where I will need to manually synchronize.

    synchronized (syncMap)
    {
    if (syncMap.containsKey(key))
    throw new AlreadyGotOneException();
    syncMap.put(key, value);
    }

    This "double synchronization" seems inelegant, and possibly wasteful.

    Is there a consensus on the best practice in this situation?

    Thanks!

    --
    ========================================================================
    Ian Pilcher
    ========================================================================
     
    Ian Pilcher, Jan 30, 2007
    #1
    1. Advertising

  2. Ian Pilcher <> wrote:
    > I've got a map that will be access by multiple threads, so I'm
    > considering using Collections.synchronizedMap to "wrap" it. There will
    > be occasions, though, where I will need to manually synchronize.


    The synchronizedMap will just prevent two actions on the map
    to happen at same time:
    e.g. when you do a .get(...), at exactly the same time when
    another thread tries to do a .put(...,...).

    If you need more actions in one go (conglomerate action), then
    you still need explicit synchronization just like you wrote:

    > synchronized (syncMap)
    > {
    > if (syncMap.containsKey(key))
    > throw new AlreadyGotOneException();
    > syncMap.put(key, value);
    > }


    > This "double synchronization" seems inelegant, and possibly wasteful.


    No, it isn't. It's necessary, but with a synchronizedMap you
    at least only need to explicitly protect conglomerate actions,
    not every single .get() and .put() as you would need for normal
    Maps when concurrently accessed in multiple threads.

    Re-requesting a lock that the thread already has, shouldn't really
    be that expensive.
     
    Andreas Leitgeb, Feb 1, 2007
    #2
    1. Advertising

  3. Ian Pilcher

    Daniel Pitts Guest

    On Jan 30, 11:18 am, Ian Pilcher <> wrote:
    > I've got a map that will be access by multiple threads, so I'm
    > considering using Collections.synchronizedMap to "wrap" it. There will
    > be occasions, though, where I will need to manually synchronize.
    >
    > synchronized (syncMap)
    > {
    > if (syncMap.containsKey(key))
    > throw new AlreadyGotOneException();
    > syncMap.put(key, value);
    > }
    >
    > This "double synchronization" seems inelegant, and possibly wasteful.
    >
    > Is there a consensus on the best practice in this situation?
    >
    > Thanks!

    That seems to be a good enough implementation.

    I have a few questions, though.
    Is the "AlreadyGotOneException" a sort of assertion against programmer
    error?
    Whether or not it is, does this mean the state of your application is
    probably foobar?

    If you are simply testing for programmer (or configuration) error,
    then it might be better to do this instead:
    oldValue = syncMap.put(key, value);
    assert oldValue != null;
    This has two side effects:
    1. No extra sync
    2. the new value does replace the old value, but an exception is still
    thrown.

    Hope this all helps,
    Daniel.
     
    Daniel Pitts, Feb 1, 2007
    #3
  4. Ian Pilcher

    Tom Hawtin Guest

    Ian Pilcher wrote:
    > I've got a map that will be access by multiple threads, so I'm
    > considering using Collections.synchronizedMap to "wrap" it. There will
    > be occasions, though, where I will need to manually synchronize.
    >
    > synchronized (syncMap)
    > {
    > if (syncMap.containsKey(key))
    > throw new AlreadyGotOneException();
    > syncMap.put(key, value);
    > }
    >
    > This "double synchronization" seems inelegant, and possibly wasteful.


    That probably wont make a particularly large impact on performance. As a
    matter of style, if I have to externally synchronise like that, then I
    do it everywhere.

    A better approach is to use a concurrent map (assuming value cannot be
    null).

    Value old = map.putIfAbsent(key, value);
    if (old != null) {
    throw new AlreadyGotOneException();
    }

    Tom Hawtin
     
    Tom Hawtin, Feb 3, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Doug Poland
    Replies:
    9
    Views:
    735
    VisionSet
    Sep 27, 2003
  2. Silvere Martin-Michiellot

    agents in Java, what is worth using?

    Silvere Martin-Michiellot, Oct 1, 2003, in forum: Java
    Replies:
    0
    Views:
    360
    Silvere Martin-Michiellot
    Oct 1, 2003
  3. Andrea Desole
    Replies:
    7
    Views:
    670
    Andrea Desole
    Nov 4, 2004
  4. j2eepgrmr

    Collections.synchronizedMap

    j2eepgrmr, Oct 19, 2005, in forum: Java
    Replies:
    5
    Views:
    23,702
    j2eepgrmr
    Oct 20, 2005
  5. mutex
    Replies:
    0
    Views:
    216
    mutex
    Jul 27, 2003
Loading...

Share This Page