HelenBlack / lambdaj

Automatically exported from code.google.com/p/lambdaj
Apache License 2.0
0 stars 0 forks source link

ArgumentsFactory.createArgument is synchronized #81

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
We use LambdaJ 2.3.1 mainly for having typesafe property-strings. The method 
ArgumentsFactory.createArgument(...) is called for every property-string 
created, but unfortunately is synchronized. This is slowing down the 
web-application.

Instead of synchronizing the whole method, you could only synchronize the 
Hashmap PLACEHOLDER_BY_INVOCATION and add an item to it only if there was no 
hit before:
<code>
  static <T> T createArgumentUnsynchronized(Class<T> clazz, InvocationSequence invocationSequence) {
    T placeholder = (T) PLACEHOLDER_BY_INVOCATION.get(invocationSequence);
    if (placeholder == null) {
      synchronized (PLACEHOLDER_BY_INVOCATION) {
        placeholder = (T) PLACEHOLDER_BY_INVOCATION.get(invocationSequence);

        if (placeholder == null) {
          placeholder = registerNewArgument(clazz, invocationSequence);
        }
      }
    }

    if ((placeholder != null) && isLimitedValues(placeholder)) {
      LIMITED_VALUE_ARGUMENTS.get().setArgument(placeholder, new Argument<T>(invocationSequence));
    }

    return placeholder;
  }
</code>

Alternatively you could use a ConcurrentHashMap instead of WeakHashMap but I 
don't know the consequences on memory usage in that case.

Original issue reported on code.google.com by le...@web.de on 25 Jan 2012 at 4:30

GoogleCodeExporter commented 8 years ago
I see your point but at the moment I cannot find a better alternative.
I cannot replace the WeakHashMap with a ConcurrentHashMap because I need the 
weak map in order to avoid memory leaks: when an argument is out of the scope 
of any method the use of the WeakHashMap makes it garbage collectable.
Also the suggested fix is not viable: invoking a get without synchronization is 
not safe (you could be in the middle of a rehashing) and invoking the get twice 
could harm the performance even worse.

Original comment by mario.fu...@gmail.com on 29 Jan 2012 at 11:37

GoogleCodeExporter commented 8 years ago
Can't you use something like 
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect
/MapMaker.html#weakKeys() ?

Original comment by m.jedy...@gmail.com on 1 Dec 2014 at 8:37