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

2020-12-16 10:08:55 浏览数 (1)

作者:iMononoke

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

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

各种锁

dangdangdang~

来慢慢讲~

1. 悲观 Vs 乐观

看下它们的流程:

它们的区别~

2. 公平 Vs 非公平

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

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

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

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

3. 可重入 Vs 不可重入

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

ReentrantLocksynchronized都是可重入锁~

  • 可重入锁的栗子:

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

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

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

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

代码语言:javascript复制
class MyClass {
     public synchronized void method1() {
        doSth();
     }
 
     public synchronized void method2() {        doAnother();
     }
}

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

  • 不可重入锁的栗子

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

代码语言:javascript复制
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的小伙伴说,可重入锁就好比,“你跟一个妹子谈恋爱,结果分手了,后来你又想谈恋爱了,你又找到那个妹子,那个妹子也还没男朋友,你们就可以减少繁琐的自我介绍等等环节直接牵手了。”

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

0 人点赞