Skip to main content

Striped Lock Class

A striped Lock/Semaphore/ReadWriteLock. This offers the underlying lock striping similar to that of ConcurrentHashMap in a reusable form, and extends it for semaphores and read-write locks. Conceptually, lock striping is the technique of dividing a lock into many stripes, increasing the granularity of a single lock and allowing independent operations to lock different stripes and proceed concurrently, instead of creating contention for a single lock.
The guarantee provided by this class is that equal keys lead to the same lock (or semaphore), i.e. if (key1.equals(key2)) then striped.get(key1) == striped.get(key2) (assuming Object.hashCode() is correctly implemented for the keys). Note that if key1 is not equal to key2, it is not guaranteed that striped.get(key1) != striped.get(key2); the elements might nevertheless be mapped to the same lock. The lower the number of stripes, the higher the probability of this happening.
There are three flavors of this class: Striped<Lock>Striped<Semaphore>, and Striped<ReadWriteLock>. For each type, two implementations are offered: strong and weak Striped<Lock>strong and weak Striped<Semaphore>, and strong and weakStriped<ReadWriteLock>Strong means that all stripes (locks/semaphores) are initialized eagerly, and are not reclaimed unless Striped itself is reclaimable. Weak means that locks/semaphores are created lazily, and they are allowed to be reclaimed if nobody is holding on to them. This is useful, for example, if one wants to create a Striped<Lock> of many locks, but worries that in most cases only a small portion of these would be in use.
Prior to this class, one might be tempted to use Map<K, Lock>, where K represents the task. This maximizes concurrency by having each unique key mapped to a unique lock, but also maximizes memory footprint. On the other extreme, one could use a single lock for all tasks, which minimizes memory footprint but also minimizes concurrency. Instead of choosing either of these extremes, Striped allows the user to trade between required concurrency and memory footprint. For example, if a set of tasks are CPU-bound, one could easily create a very compact Striped<Lock> of availableProcessors() * 4 stripes, instead of possibly thousands of locks which could be created in a Map<K, Lock> structure.

Source : Google Guava Project Documentation.


Popular posts from this blog

Some good links -- Client side performance tips -- New exciting Framework, Must read. -- Very good resource to see various javaee projects and explore enterprise architecture and design concepts. -- Lots of interesting open source projects by eclipse -- the main project for supporting more dynamic languages to jvm. -- EcmaScript parser and -- Good place to learn patterns -- This will validate your website css and js -- An example of SHA1 collision attack.

@MappedSuperclass vs. @Inheritance

MappedSuperClass must be used to inherit properties, associations, and methods. Entity inheritance must be used when you have an entity, and several sub-entities. You can tell if you need one or the other by answering this questions: is there some other entity in the model which could have an association with the base class? If yes, then the base class is in fact an entity, and you should use entity inheritance. If no, then the base class is in fact a class that contains attributes and methods that are common to several unrelated entities, and you should use a mapped superclass. For example: You can have several kinds of messages: SMS messages, email messages, or phone messages. And a person has a list of messages. You can also have a reminder linked to a message, regardless of the kind of message. In this case, Message is clearly an entity, and entity inheritance must be used. All your domain objects could have a creation date, modification date and ID, and you could thus

Hashmap Keyset and EntrySet difference.

If you're concerned about performance when iterating through your hash map, I suggest you have a look at  LinkedHashMap . From the docs: Iteration over the collection-views of a LinkedHashMap requires time proportional to the size of the map, regardless of its capacity. Iteration over a HashMap is likely to be more expensive, requiring time proportional to its capacity. HashMap.entrySet() The source-code for this implementation is available. The implementation basically just returns a new  HashMap.EntrySet . A class which looks like this: private final class EntrySet extends AbstractSet < Map . Entry < K , V >> { public Iterator < Map . Entry < K , V >> iterator () { return newEntryIterator (); // returns a HashIterator... } // ... } and a  HashIterator  looks like private abstract class HashIterator < E > implements Iterator < E > { Entry < K , V > next ; // next entry to ret