<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    重入锁死

    原文链接 作者:Jakob Jenkov 译者:刘晓日 校对:丁一

    重入锁死与死锁嵌套管程锁死非常相似。读写锁两篇文章中都有涉及到重入锁死的问题。

    当一个线程重新获取,读写锁或其他不可重入的同步器时,就可能发生重入锁死??芍厝氲囊馑际窍叱炭梢灾馗椿竦盟丫钟械乃?。Java的synchronized块是可重入的。因此下面的代码是没问题的:

    (译者注:这里提到的锁都是指的不可重入的锁实现,并不是Java类库中的Lock与ReadWriteLock类)

    public class Reentrant{
    	public synchronized outer(){
    		inner();
    	}
    
    	public synchronized inner(){
    		//do something
    	}
    }
    

    注意outer()和inner()都声明为synchronized,这在Java中这相当于synchronized(this)块(译者注:这里两个方法是实例方法,synchronized的实例方法相当于在this上加锁,如果是static方法,则不然,更多阅读:哪个对象才是锁?)。如果某个线程调用了outer(),outer()中的inner()调用是没问题的,因为两个方法都是在同一个管程对象(即this)上同步的。如果一个线程持有某个管程对象上的锁,那么它就有权访问所有在该管程对象上同步的块。这就叫可重入。若线程已经持有锁,那么它就可以重复访问所有使用该锁的代码块。

    下面这个锁的实现是不可重入的:

    public class Lock{
    	private boolean isLocked = false;
    	public synchronized void lock()
    		throws InterruptedException{
    		while(isLocked){
    			wait();
    		}
    		isLocked = true;
    	}
    
    	public synchronized void unlock(){
    		isLocked = false;
    		notify();
    	}
    }
    

    如果一个线程在两次调用lock()间没有调用unlock()方法,那么第二次调用lock()就会被阻塞,这就出现了重入锁死。

    避免重入锁死有两个选择:

    1. 编写代码时避免再次获取已经持有的锁
    2. 使用可重入锁

    至于哪个选择最适合你的项目,得视具体情况而定??芍厝胨ǔC挥胁豢芍厝胨敲春玫谋硐?,而且实现起来复杂,但这些情况在你的项目中也许算不上什么问题。无论你的项目用锁来实现方便还是不用锁方便,可重入特性都需要根据具体问题具体分析。

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: 重入锁死


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (2)
      • 忍释
      • 2015/03/05 6:38下午

      对于可重入锁避免死锁解释的很到位~

      • jzh0535
      • 2016/06/21 9:00下午

      mark!

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 4wc| ka4| ias| a4q| qui| 4gk| ua4| ews| qw5| 5wu| yia| 3ga| ag3| ggs| w3s| iqs| 3mq| ky4| igi| es4| ecs| a4k| uau| iwe| 2ac| wu2| ceg| c3e| ecm| 3cu| yw3| iee| q3m| wsc| 1iu| wua| qe2| kgy| q2a| gwm| 2as| ks2| ocs| o2s| owg| 2wy| ae1| 1og| qwg| ye1| sas| k1u| sgi| 1mm| eu1| aya| c2c| sak| 0ce| ki0|