java - 为什么这个程序中同一个对象没有死锁 - Java 多线程

标签 java multithreading synchronized

我有以下三门类(class)。 Main、两个线程和Obj,其方法是同步的

public class DeadLocks {

    public static void main(String[] args) {
        SyncObj so = new SyncObj();
        ThreadObj to = new ThreadObj(so);
        ThreadObj1 to1 = new ThreadObj1(so);

        to.start();
        to1.start();
    }
}

class SyncObj {
    synchronized void foo() {
        System.out.println("Foo Started");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        bar();
    }

    synchronized void bar() {
        System.out.println("bar started");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        foo();
    }

}

class ThreadObj1 extends Thread {
    SyncObj so;

    public ThreadObj1(SyncObj so) {
        this.so = so;
    }

    @Override
    public void run() {
        so.bar();
    }
}

class ThreadObj extends Thread {
    SyncObj so;

    public ThreadObj(SyncObj so) {
        this.so = so;
    }

    @Override
    public void run() {
        so.foo();
    }
}

在上面的代码中,我在同一对象上调用同步方法。两个方法都是同时执行和互相调用的,不存在死锁的情况。有人能解释一下为什么吗?抱歉问了这么愚蠢的问题。

最佳答案

据我所知,这两种情况都使用相同的对象 (so)。所以不存在僵局的情况。您需要锁定两个或多个对象,其中每个关键部分都需要锁定,而不是它所持有的锁定。另一个锁由“另一个”线程持有。

令人困惑,这会启发:“https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

在您描述的场景中,您永远不会出现死锁。在这种情况下,只有一个正在共享和同步的 so

让我举个例子来说明一下:

假设安迪和桑迪正在玩两个足球B1B2

现在进一步假设安迪和桑迪分别拥有球B1B2。例如,安迪 (Andy) 拥有球 B1,桑迪 (Sandy) 拥有球 B2

现在他们设计了一种游戏,其中他们每个人都需要两个球。 现在桑迪也想要球B1,同时安迪想要B2

他们俩都不能放弃他们所持有的球。安迪不会放弃B1,反之亦然。

So both of them cannot continue and are stuck. We call this a deadlocked situation.

希望这个例子有帮助。您可以发挥您的想象力,将比赛中的球数增加到 3 或 4 个(依此类推……)和/或增加玩家数量。

关于java - 为什么这个程序中同一个对象没有死锁 - Java 多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49542187/

相关文章:

java - CompletableFuture : after async call, 当前线程中的处理结果

java - 有条件地定义同步块(synchronized block)

java - 如何将spring hibernate mysql迁移到mongodb

java - (R.layout.splash);飞溅无法解析或不是一个字段

java - 简单的 If 语句不起作用 (BlueJ)

java - 如何从非 Activity 类开始一个 Activity 并等到它完成?

java - Java 如何处理以下场景?

java - 如何从 jpcap 中查找信息字段

c - 使用 winapi 在 C 语言中为 shell 实现管道

android - android handlemessage可以重入吗?