例子说明
public class ReGetLock implements Runnable {
@Override
public void run() {
get();
}
public synchronized void get() {
System.out.println(Thread.currentThread().getId());
set();
}
public synchronized void set() {
System.out.println(Thread.currentThread().getId());
}
public static void main(String[] args) {
ReGetLock rgl = new ReGetLock();
new Thread(rgl).start();
}
}
执行代码的线程到底能不能进入到set方法呢?
因为线程rgl先调用了get方法,获取到了ReGetLock对象的锁,那么当线程rgl想进入标有synchronized 关键字的set方法时,会被阻塞住,一直等待吗?
其实是不会的,在JAVA里面,当某个线程试图获得一个已经由它自己持有的锁,那么这个请求会成功。不然会出现死锁。
因此像synchronized 这种加锁机制,线程是可重入的。
虽然某个线程试图获得一个已经由它自己持有的锁,那么这个请求会成功,但是再次获得锁的这个动作仍然是有开销的,里面会涉及到一些同步操作。
思考:
如果当共享资源不存在多线程竞争的情况,那么当线程重入时的同步开销能否去掉呢?这个其实就涉及到锁偏向的问题了。
本文通过一个具体的Java代码示例,解释了线程如何能够重新获得已由其自身持有的锁,即所谓的重入锁概念,并探讨了在没有多线程竞争的情况下如何减少锁的开销。





