(有关线程同步)同步块用的锁定义为non-static型Object时,问题详见内容

qq_42998816 2021-08-03 17:53:57
public class ForDeadlock {
    public static void main(String[] args) {
        Counter2 c1 = new Counter2();
        Counter2 c2 = new Counter2();
        new Thread(()->c1.add(1)).start();
        new Thread(()->c2.dec(1)).start();
        System.out.println("c1.value = " + c1.value);
        System.out.println("c1.another = " + c1.another);
        System.out.println("c2.value = " + c2.value);
        System.out.println("c2.another = " + c2.another);
    }
}
class  Counter2{
    public final Object lockA=new Object();
    public final Object lockB=new Object();
    public int count=0;
    public int value=0;
    public int another=0;
//    public synchronized void add(int n){
//        if (n<0)dec(-n);
//        else count+=n;
//    }
//    public synchronized void dec(int n){
//        count-=n;
//    }
    public void add(int n){
        synchronized (lockA) {
            value+=n;
            sleep1s();
            synchronized (lockB) {
                another+=n;
                sleep1s();
            }
        }
    }
    public void dec(int n){
        synchronized (lockB) {
            another-=n;
            sleep1s();
            synchronized (lockA) {
                value-=n;
                sleep1s();
            }
        }
    }
    void sleep1s(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

我的计数器类的两把锁都是 non static 型,按理说每个实例都有各自的两把锁,互不干扰,也不会死锁,但从结果来看,为什么对象1获取不到锁B ,而对象2也获取不到锁A呢?下面是在IDEA中的运行结果,四行结果输出到控制台后还停了一两秒,然后程序自动结束(而不是双方一直等待获得另一把锁)

c1.value = 1
c1.another = 0
c2.value = 0
c2.another = -1

Process finished with exit code 0

...全文
418 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
郑老师 老师 2021-08-03
  • 打赏
  • 举报
回复 1

请在第6行之后加上
Thread.sleep(1000);

qq_42998816 2021-08-03
  • 举报
回复
@郑老师 ,看来沉睡对线程来说是如此重要的事,没睡提前出结果就不一样了
郑老师 老师 2021-08-03
  • 举报
回复
@qq_42998816 多线程的执行顺序一般来说没办法确定的。有的时候为了测试,就只好多睡睡。 当然有的时候用一下join也是可以的。
杨涛 助教 2021-08-03
  • 打赏
  • 举报
回复

main方法的线程优先级高,两个线程由于都休眠了两秒,main方法先执行完,两个线程还没执行完成,所以打印出来的数据没变

qq_42998816 2021-08-03
  • 举报
回复
@杨涛 为什么第一个线程获取不到锁B,第二个线程获取不到锁A
杨涛 助教 2021-08-03
  • 举报
回复
@qq_42998816 你把sleep去掉就可以了
qq_42998816 2021-08-03
  • 举报
回复
@杨涛 我本来是没有加sleep的,加了是为了方便看到线程死锁,我的计数器的两把锁没有用static关键字修饰,按理说每个对象拥有各自的锁A和锁B,对象间的锁互不干涉,为何此时第一个线程用第一个对象加了锁A以及第二个线程用第二个对象加了锁B之后,第一个线程得不到自己的锁B呢
1条回复

4,023

社区成员

发帖
与我相关
我的任务
社区描述
为初学Java的大学生提供一个学习、交流的社区。 社区包括:技术文章、学习任务、在线课程、在线编程练习。
javajava-eeeclipse 高校
社区管理员
  • zhrb
  • 驼同学.
  • 兰翔呀
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

社区板块说明:
1. Java技术:包含Java技术的各种新闻、文章。
2. 教学频道:包含Java基础技术与Java教学中常用的一些文章。建议初学者、在线学习的同学在这里交流、提问、浏览课程学习相关文章。
3. 学习任务:老师发布的教学任务。
4. 其他技术:其他技术文章。

社区链接说明:
1. 在线学习:本社区对应的在线课程(免费学习)。
2. 编程练习:本社区使用的在线编程练习平台(加入在线课程后,免费练习)。
3. 项目实例:一个简单的Java项目示例。
 

试试用AI创作助手写篇文章吧