查看原文
其他

码妞:Java的一堆锁是干嘛的?能锁住体重吗?

Isabella 码个蛋 2019-06-22
码个蛋(codeegg)第 643 次推文


作者:iMononoke

博客:https://juejin.im/user/5c629a3051882562191755d8


上次就说会被码妞“烦”了,果然她来了……



各种锁



dangdangdang~



来慢慢讲~


1. 悲观 Vs 乐观


看下它们的流程:



它们的区别~



2. 公平 Vs 非公平




公平锁和非公平锁的示例:



公平锁就是新来的线程乖乖排到队列最后去等待着~



非公平锁就是新来的线程先试着插队能不能成功(获取到锁),成功的话,就在当前运行的线程执行完成后就拿到锁了,开始它的执行过程;

如果插队失败,就和公平锁的流程一样,排到队伍最后去了。


3. 可重入 Vs 不可重入


下面我们来看可重入锁和不可重入锁~



ReentrantLocksynchronized都是可重入锁~


  • 可重入锁的栗子:


当一个线程执行到某个synchronized方法时,

比如说method1,在method1中又会调用另外一个synchronized方法method2,

此时线程不必重新去申请锁,而是可以直接执行方法method2。


看下面这段代码就知道了:


class MyClass {
    public synchronized void method1() {
        doSth();
    }

    public synchronized void method2() {
        doAnother();
    }
}


如果不是可重入锁的话,method2可能不会被当前线程执行,可能造成死锁。


  • 不可重入锁的栗子


用自旋锁来模拟,代码如下:


public class UnreentrantLock {

private AtomicReference<Thread> owner = new AtomicReference<Thread>();

public void lock() {
    Thread current = Thread.currentThread();
    //这句是很经典的“自旋”语法,AtomicInteger中也有
    for (;;) {
        if (!owner.compareAndSet(null, current)) {
            return;
        }
    }
}

    public void unlock() {
        Thread current = Thread.currentThread();
        owner.compareAndSet(current, null);
    }
}


同一线程两次调用lock()方法,如果不执行unlock()释放锁的话,第二次调用自旋的时候就会产生死锁。



有个叫midnight的小伙伴说,可重入锁就好比,“你跟一个妹子谈恋爱,结果分手了,后来你又想谈恋爱了,你又找到那个妹子,那个妹子也还没男朋友,你们就可以减少繁琐的自我介绍等等环节直接牵手了。”


以上观点不代表码仔想法,码仔也不表示赞同,谢谢~



近期文章:



今日问题:

想听码仔讲哪些Java芝士点?



快来码仔社群解锁新姿势吧!社群升级:Max你的学习效率


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存