what is the difference b/w intrinsic locking, client side locking & extrinsic locking ?
What is the best way to create a thread safe class ?
which kind of locking is prefered & why ?
An intrinsic lock (aka monitor lock) is an implicit internal entity associated with each instance of objects. The intrinsic lock enforces exclusive access to an object's state. Here 'access to an object' refers to an instance method call. When a synchronized method is called from a thread it needs to acquire the intrinsic lock.
It is not possible to interrupt a thread waiting to acquire a lock, or attempt to acquire a lock without being willing to wait for it forever. It gives option for timed, polled or Interruptible locks helping to avoid probabilistic deadlock. Lock has to be released manually in a finally block once we have modified the protected state.
When multiple locks are acquired, they must be released in the same order, and all locks must be released in the same lexical scope in which they were acquired. Ability to implement non-block-structured locking.
One can have couple of methods synchronized under one lock and other methods under a different lock. This allows more concurrency and also increases overall performance. Attention reader! Don’t stop learning now.
Explicit - locking using concurrent lock utilities like Lock interface. eg - ConcurrentHashMap
Intrinsic - locking using synchronized
.
Client side locking - Classes like ConcurrentHashMap
doesn't support Client side locking because get method is not using any kind of lock. so although you put a lock over its object like synchronized (object of ConcurrentHashMap
) still some other thread can access object of ConcurrentHashMap
.
Classes having all set get methods Explicit or Intrinsic locks are supporting client side locking. As some client code come and lock over that object. below is example of Vector
public static Object getLast(Vector list) {
synchronized (list) {
int lastIndex = list.size() - 1;
return list.get(lastIndex);
}
}
public static void deleteLast(Vector list) {
synchronized (list) {
int lastIndex = list.size() - 1;
list.remove(lastIndex);
}
}
I would highly recommend you to read "Java Concurrency In Practice" by Brian Goetz. It is an excellent book that will help you to understand all the concepts about concurrency!
About your questions, I am not sure if I can answer them all, but I can give it a try. Most of the times, if the question is "what is the best way to lock" etc, the answer is always it depends on what problem you try to solve.
Question 1:
What you try to compare here are not exactly comparable;
Java provides a built in mechanism for locking, the synchronized
block. Every object can implicitly act as a lock for purposes of synchronization; these built-in locks are called intrinsic locks.
What is interesting with the term intrinsic
is that the ownership of a lock is per thread and not per method invocation. That means that only one thread can hold the lock at a given time. What you might also find interesting is the term reentrancy
, which allows the same thread to acquire the same lock again. Intrinsic locks are reentrant.
Client side locking, if I understand what you mean, is something different. When you don't have a thread safe class, your clients need to take care about this. They need to hold locks so they can make sure that there are not any race conditions.
Extrinsic locking is, instead of using the built in mechanism of synchronized block which gives you implicit locks to specifically use explicit locks. It is kind of more sophisticate way of locking. There are many advantages (for example you can set priorities). A good starting point is the java documentation about locks
Question 2: It depends :) The easiest for me is to try to keep everything immutable. When something is immutable, I don't need to care about thread safety anymore
Question 3: I kind of answered it on your first question
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With