美文网首页
Java并发之四:正确使用synchronized

Java并发之四:正确使用synchronized

作者: 亨小利霍 | 来源:发表于2018-03-31 01:20 被阅读0次

    synchronized 同步,又称同步锁,以下简称 "sync"。

    虽然synchronized的写法有七八种(见下例), 其实只分两类,一个对象实例锁,一个类锁。

    对象实例锁

    1、synchronized void method() :普通sync方法,锁调用该方法的对象实现
    2、synchronized(this) :sync this,锁this
    3、synchronized(objRef) :sync指定变量
    4、synchronized(memberRef) :sync类成员变量
    5、synchronized(staticMemberRef) :sync静态类成员变量

    类锁

    6、synchronized static void method() :sync静态方法
    7、synchronized(Sample.class) :sync类锁
    8、synchronized(this.getClass()) :sync类锁

    规则

    1、对象锁与类锁互相独立,每个实例、每个类都只有一个锁;

    2、同为对象锁的sync调用,判断是否同一个对象引用,如同则存在同步竞争;注意Integer/String的缓存坑,两个变量实为一个。

    3、同为类锁的sync调用,判断是否同一个Class类,如同则存在同步竞争。

    4、非sync方法,任何时候都不受同步锁影响。

    5、synchronized关键字是不能继承的,它不是方法签名。

    6、sync类成员变量,该类的不同实例持有的普通成员变量,对应的是该成员变量的不同实例,它们之间是不存在锁竞争的。

    7、sync静态类成员变量,该类的不同实例持有的是同一个成员变量实例,所以它们之间是存在锁竞争的。但与该静态成员变量所在类的类锁是互相独立的。

    实现原理

    sync同步锁,是隐式锁,在进入sync临界区时由jvm自动获取,退出时自动释放。

    sync同步锁有三个属性:
        依赖的对象实例/类引用;(对象的锁,锁的对象,同义)
        WaitSet,等待池列表,所有调用wait()方法的线程都会进入该列表,等待池列表中的线程不会去竞争sync锁。待其他进入sync临界区的线程调用notify()后或wait(long)的时间到,会退出本区进入EntryList区;
        EntryList,锁池队列,所有尝试获取sync锁,进入该锁的EntryList,待当前持有锁的线程释放后,按非公平方式分配锁;

    wait()方法只能sync临界区内使用,因为wait()的语义只有两个:一就是释放sync锁,未持有锁谈何释放;二是进入WaitSet区,等待notify或时间到;

    notify() 会从WaitSet列表中随机唤醒一个;

    notifyAll()会将WaitSet列表中所有线程都唤醒,整体进入锁池去竞争sync锁;

    正确使用

    wait() 应配合while循环使用,不应使用if,务必在wait()调用前后都检查条件,如果不满足,必须调用notify()唤醒下一条线程来处理,自己回去继续wait()直至条件满足再往下执行。

    notifyAll()将所有WaitSet中的线程从等待池唤醒,全部进入锁池竞争去sync锁,最终也只有一个线程能获取锁去执行,唤醒+竞争锁池本身是线程上下文的重操作,对性能产生不良影响。滥用notifyAll()有可能导致“惊群效应”。

    notify() 是对notifyAll()的一个优化,但它有很精确的应用场景,并且要求正确使用。不然可能导致死锁。正确的场景应该是 WaitSet中等待的是相同的条件,唤醒任一个都能正确处理接下来的事项,如果唤醒的线程无法正确处理,务必确保继续notify()下一个线程,并且自身需要重新回到WaitSet中(参见上一条)。导致死锁的原因是notify()随机唤醒了一条线程,但它既无法正确改变条件,也不叫醒另一个兄弟来搞,就会产生一个情况:锁池中的队列空了,等待池中有一堆线程,但不会再被唤醒永远等待。


    参考
            《Java编程思想》之《notify()vs.notifyAll()》

    相关文章

      网友评论

          本文标题:Java并发之四:正确使用synchronized

          本文链接:https://www.haomeiwen.com/subject/hhwwcftx.html