java.concurrent.ReentrantLock - why we want to acquire the same lock multiple times [duplicate]

时光毁灭记忆、已成空白 提交于 2019-12-04 08:13:17

Consider the following case in which you need a set of operations which isn't atomic, be atomic. For example you may want to set a value of an array but return its current value upon setting. (try-finally removed for brevity).

final ReentrantLock lock = new ReentrantLock();

final Object[] objects = new Object[10]
public Object setAndReturnPrevious(int index, Object val){
   lock.lock();
      Object prev = get(index);
      set(index,val);
      return prev;
   lock.unlock();
}
public void set(int index, Object val){
    lock.lock();
         objects[index] = val;
    lock.unlock();
}
public Object get(index index){...}

If ReentrantLock wasn't reentrant you would deadlock at get(index)

Suppose in a class you have two methods m1 and m2, both synchronized and m2 is calling m1. In that case if thread a has taken a lock on m1 and taking a lock again is not allowed then that thresad will keep on waiting for calling m2 (as it already has a the lock)

Consider this synchronized example. The same applies to lock but with more code.

synchronized int getSum() {
     return getValue() + getOtherValue();
}

synchronized int getValue() {
     return value;
}

synchronized int getOtherValue() {
     return value;
}

The only way to avoid being re-entrant is to create locked and unlocked versions of each method. However what if you have two instances A and B. A calls B which calls A. How does B know not to call a synchronized method in A.

Some argue that reentrant locking should be avoided. In a critical section, you should know exactly what is going on. If a local critical section may call a foreign code that may call a local code back, that seems pretty complicated and potentially dangerous. It is better to have just a few well defined critical sections containing only local code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!