Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

using ConcurrentHashMaps

Thread view: 
Vaibhav - 20 Apr 2007 16:17 GMT
Hi,

I have following code in my program. Is it possible to use a
ConcurrentHashMap in this scenario?

private Map mymap = Collections.synchronizedMap(new HashMap());

public MyHandle getHandle(String id) {
       MyHandle handle = null;
       MyHandle tmpHandle;

       synchronized(mymap) {
           Iterator it = this.mymap.values().iterator();
           while(it.hasNext()) {
               tmpHandle = (MyHandle)it.next();
               if(id.equals(MyHandle.getId())) {
                   handle = tmpHandle;
                   break;
               }
           }
       //}

       return handle;
   }

Thanks!
Robert Klemme - 20 Apr 2007 16:30 GMT
> I have following code in my program. Is it possible to use a
> ConcurrentHashMap in this scenario?
>
> private Map mymap = Collections.synchronizedMap(new HashMap());

If you access your map only in synchronized blocks like below you do not
need a synchronizedMap.

> public MyHandle getHandle(String id) {
>         MyHandle handle = null;
[quoted text clipped - 13 lines]
>         return handle;
>     }

Certainly you can use a ConcurrentHashMap but it would be more efficient
if you used the id as map key.

Kind regards

    robert
Vaibhav - 20 Apr 2007 16:40 GMT
> > I have following code in my program. Is it possible to use a
> > ConcurrentHashMap in this scenario?
[quoted text clipped - 3 lines]
> If you access your map only in synchronized blocks like below you do not
> need a synchronizedMap.

I do have to access my map in other parts of the code, where I do not
need to synchronize.
It is not clear to me how the code should look if I use a
concurrentHashMap..
My question is that can I avoid synchronize block in this case if I
were using a concurrentHashMap.

> > public MyHandle getHandle(String id) {
> >         MyHandle handle = null;
[quoted text clipped - 16 lines]
> Certainly you can use a ConcurrentHashMap but it would be more efficient
> if you used the id as map key.

I unerstand the efficiency part when using id as key. Can you explain
how that will be thread safe?

Thanks for your help!
Robert Klemme - 20 Apr 2007 17:00 GMT
>>> I have following code in my program. Is it possible to use a
>>> ConcurrentHashMap in this scenario?
[quoted text clipped - 4 lines]
> I do have to access my map in other parts of the code, where I do not
> need to synchronize.

Ah, ok.  Just wanted to make sure.

>  It is not clear to me how the code should look if I use a
> concurrentHashMap..

You can just replace your map with the CHM and remove the synchronized
blocks.  Additionally you do need to change the code that modifies the
map (check the interface) in order to remedy the effects of an update
that occurs in another thread between your testing of a key and
inserting it.

> My question is that can I avoid synchronize block in this case if I
> were using a concurrentHashMap.
[quoted text clipped - 19 lines]
> I unerstand the efficiency part when using id as key. Can you explain
> how that will be thread safe?

That ConcurrentHashMap is partitioned internally (you can see it in the
source code).  Also, no synchronized primitives are used internally but
a ReadWriteLock which is faster than the former.

    robert
Vaibhav - 20 Apr 2007 17:18 GMT
> >>> I have following code in my program. Is it possible to use a
> >>> ConcurrentHashMap in this scenario?
[quoted text clipped - 15 lines]
> that occurs in another thread between your testing of a key and
> inserting it.

thats sounds good. I have another question along the same line.. under
which scenario we should not remove synchronize block while migrating
to CHM? If there is such a block.. is it still ok to use
synchronize(m) or just stay with SHM in that case..

> > My question is that can I avoid synchronize block in this case if I
> > were using a concurrentHashMap.
[quoted text clipped - 23 lines]
> source code).  Also, no synchronized primitives are used internally but
> a ReadWriteLock which is faster than the former.

I guess my confusion is because I am not clear how the local variables
in the method are being effected by multiple threads..
will the threads be sharing tmpHandle.. I am thinking it could be a
problem if they did and we synchronized on id..

thanks again! :)
Tom Hawtin - 20 Apr 2007 17:49 GMT
> thats sounds good. I have another question along the same line.. under
> which scenario we should not remove synchronize block while migrating
> to CHM? If there is such a block.. is it still ok to use
> synchronize(m) or just stay with SHM in that case..

Synchronised blocks are not much use when it comes to ConcurrentHashMap,
as it doesn't use synchronized itself.

Iterators (of ConcurrentHashMap) happen to behave reasonably in the face
concurrent modification. Otherwise atomic operations need to be single
operations, hence the extra methods in the ConcurrentMap interface.

Tom Hawtin
Vaibhav - 20 Apr 2007 18:35 GMT
> > thats sounds good. I have another question along the same line.. under
> > which scenario we should not remove synchronize block while migrating
[quoted text clipped - 9 lines]
>
> Tom Hawtin

Hi Tom,

Can you throw som e light on how usage of local variables is effected
in a multi-threaded environment.. all examples I found refer to
instance variables and do not say anything about local vars.

Vaibhav
Robert Klemme - 20 Apr 2007 18:47 GMT
>>> thats sounds good. I have another question along the same line.. under
>>> which scenario we should not remove synchronize block while migrating
[quoted text clipped - 12 lines]
> in a multi-threaded environment.. all examples I found refer to
> instance variables and do not say anything about local vars.

Local variables are thread local.  However, if you have a local variable
of a reference type (i.e. everything that is not a int, long etc.) and
the reference is shared among threads all sorts of things can happen
depending on the usage patterns.

I get the impression that you first should get the basics right.  I
suggest you get yourself a copy of Doug Lea's Book about concurrent
programming in Java and read up on the basic concepts or at least read
some primer on the web about the matter.

Kind regards

    robert
Vaibhav - 20 Apr 2007 18:57 GMT
> >>> thats sounds good. I have another question along the same line.. under
> >>> which scenario we should not remove synchronize block while migrating
[quoted text clipped - 28 lines]
>
> - Show quoted text -

Thanks for quick clarification. I have got hold of that book and will
be reading it as time permits..
Tom Hawtin - 20 Apr 2007 16:48 GMT
> I have following code in my program. Is it possible to use a
> ConcurrentHashMap in this scenario?

Yup.

The iterator does not throw ConcurrentModificationException. If an
element is added or removed from the map during the operation, you may
see it, or you may not.

From ConcurrentHashMap.values:

"The view's iterator is a "weakly consistent" iterator that will never
throw ConcurrentModificationException, and guarantees to traverse
elements as they existed upon construction of the iterator, and may (but
is not guaranteed to) reflect any modifications subsequent to construction."

private final ConcurrentMap<Long,MyHandle> map =
    new ConcurrentHashMap<Long,MyHandle>();

public MyHandle getHandle(String id) {
    if (id == null) {
        throw new NullPointerException();
    }

    for (MyHandle handle : map.values()) {
        if (id.equals(handle.getId())) {
            return handle;
        }
    }

    return null;
}

Tom Hawtin
Vaibhav - 20 Apr 2007 17:24 GMT
> The iterator does not throw ConcurrentModificationException. If an
> element is added or removed from the map during the operation, you may
[quoted text clipped - 9 lines]
> private final ConcurrentMap<Long,MyHandle> map =
>      new ConcurrentHashMap<Long,MyHandle>();

Are we required to use "final" for ConcurrentMap variables.. or that
was just an example..

> public MyHandle getHandle(String id) {
>      if (id == null) {
[quoted text clipped - 10 lines]
>
> }

Thanks for  your help!
Tom Hawtin - 20 Apr 2007 17:46 GMT
>> private final ConcurrentMap<Long,MyHandle> map =
>>      new ConcurrentHashMap<Long,MyHandle>();
>
> Are we required to use "final" for ConcurrentMap variables.. or that
> was just an example..

Use final on fields whenever possible. It helps understanding what is
going on with the variable. The frequency I have to spend way too much
time and concentration on dealing with missing finals is not funny. In
some circumstances, it can also make unsafe publication thread-safe,
which is another thing that then need not be worried about.

Tom Hawtin
idaku2@gmail.com - 20 Apr 2007 17:45 GMT
> public MyHandle getHandle(String id) {
>      if (id == null) {
[quoted text clipped - 4 lines]
>          if (id.equals(handle.getId())) {
>              return handle;

Hi

Why did you use if clause and explicitly throw NullPointerException if
id is null, and not use id.equals to throw the same exception?  I'am
still newbie, and learning exception handling mechanism.
Tom Hawtin - 20 Apr 2007 17:59 GMT
>> public MyHandle getHandle(String id) {
>>      if (id == null) {
[quoted text clipped - 4 lines]
>>          if (id.equals(handle.getId())) {
>>              return handle;

> Why did you use if clause and explicitly throw NullPointerException if
> id is null, and not use id.equals to throw the same exception?  I'am
> still newbie, and learning exception handling mechanism.

What happens if your map is empty...?

Tom Hawtin
Vaibhav - 20 Apr 2007 18:03 GMT
> > public MyHandle getHandle(String id) {
> >      if (id == null) {
[quoted text clipped - 10 lines]
> id is null, and not use id.equals to throw the same exception?  I'am
> still newbie, and learning exception handling mechanism.

It's a good point. I am working with legacy code here, so I am not
sure why this was done. My understanding is that the iteration over
the map was synchronized while the if statement was not synchronized.
The if statement just prevents synchronization in cases where we will
end up throwing an exception anyways.. A good design may just avoid
this issue by making sure this method does not get called by a null
value. So, this may just have been a hack which needs to be removed at
some point..
Vaibhav - 20 Apr 2007 18:29 GMT
I came across usage of
Collections.synchronizedMap(new ConcurrentHashMap())
Can this be useful?
Tom Hawtin - 20 Apr 2007 19:01 GMT
> I came across usage of
> Collections.synchronizedMap(new ConcurrentHashMap())
> Can this be useful?

I think that's just confused...

You could conceivably make use of a ConcurrentHashMap passed through
synchronizedMap if you have another reference to the original. However,
I would use synchronized explicitly in those cases.

OTOH, I guess there are some corner cases. For instances, making use of
unsynchronised iterators.

Tom Hawtin
Robert Klemme - 20 Apr 2007 22:46 GMT
>> I came across usage of
>> Collections.synchronizedMap(new ConcurrentHashMap())
[quoted text clipped - 5 lines]
> synchronizedMap if you have another reference to the original. However,
> I would use synchronized explicitly in those cases.

I cannot think of a scenario where that would be useful.  Do you have an
example?  I mean, usually you would use CHM in order to get faster and
more efficient synchronization as with synchronized, wouldn't you?

> OTOH, I guess there are some corner cases. For instances, making use of
> unsynchronised iterators.

I am not sure what you mean by this.

Kind regards

    robert
Tom Hawtin - 21 Apr 2007 01:32 GMT
>>> I came across usage of
>>> Collections.synchronizedMap(new ConcurrentHashMap())
[quoted text clipped - 9 lines]
> example?  I mean, usually you would use CHM in order to get faster and
> more efficient synchronization as with synchronized, wouldn't you?

Consider the case when you want a lock on all of your writes, but not
your reads. Perhaps because constructing objects for writes interferes,
or you have to return a map that client code has some (partial)
expectation that it will be a synchronised map. You can use the wrapped
map for writes and the raw map for reads. However, that'd probably be
considerably confusing.

>> OTOH, I guess there are some corner cases. For instances, making use
>> of unsynchronised iterators.
>
> I am not sure what you mean by this.

In the original posting there is a synchronised loop. Map the map a
synchronised concurrent map, and you can lose that synchronised whilst
still being able to use the lock for multiple operations that should be
atomic (with regards to everything but that iterator).

Tom Hawtin
Robert Klemme - 21 Apr 2007 10:07 GMT
>>>> I came across usage of
>>>> Collections.synchronizedMap(new ConcurrentHashMap())
[quoted text clipped - 16 lines]
> map for writes and the raw map for reads. However, that'd probably be
> considerably confusing.

I see.  That makes sense.  Although in that case I'd rather use a
reentrant lock as this has shown to be faster than synchronized in my tests.

>>> OTOH, I guess there are some corner cases. For instances, making use
>>> of unsynchronised iterators.
[quoted text clipped - 5 lines]
> still being able to use the lock for multiple operations that should be
> atomic (with regards to everything but that iterator).

Yeah, basically a similar scenario as above: you use the CHM for "basic"
thread safety and add synchronization mechanisms for special scenarios /
methods / operations.

Thanks for clarifying!

Kind regards

    robert


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.