JAVA-基础语法-多线程基础-锁

举报
Photon 发表于 2020/12/17 12:17:46 2020/12/17
【摘要】 JAVA-基础语法-多线程基础-锁

可重入锁

Java 的线程锁是可重入锁。 获取锁的时候,不但要判断是否是第一次获取,还要记录这是第几次获取。每获取一次锁,记录+1,每退出synchronized块,记录-1,减到0的时候,才会真正释放锁。

即允许同一个线程重复获取同一个锁。

线程执行到add()方法内部,说明它已经获取了当前实例的this锁。如果传入的n < 0,将在add()方法内部调用dec()方法。由于dec()方法也需要获取this锁
   
public class Counter {
   private int count = 0;

   public synchronized void add(int n) {
       if (n < 0) {
           dec(-n);
      } else {
           count += n;
      }
  }

   public synchronized void dec(int n) {
       count += n;
  }
}

死锁

两个线程各自持有不同的锁,都在尝试获取对方的锁。造成双方无限等待下去。死锁发生后没有任何机制可以解除,只能强制结束JVM。

public void add(int m) {
   synchronized(lockA) { // 获得lockA的锁
       this.value += m;
       synchronized(lockB) { // 获得lockB的锁
           this.another += m;
      } // 释放lockB的锁
  } // 释放lockA的锁
}

public void dec(int m) {
   synchronized(lockB) { // 获得lockB的锁
       this.another -= m;
       synchronized(lockA) { // 获得lockA的锁
           this.value -= m;
      } // 释放lockA的锁
  } // 释放lockB的锁
}

如何避免?

线程获取锁的顺序要一致。

public void dec(int m) {
   synchronized(lockA) { // 获得lockA的锁
       this.value -= m;
       synchronized(lockB) { // 获得lockB的锁
           this.another -= m;
      } // 释放lockB的锁
  } // 释放lockA的锁
}

####

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。