这段代码会导致死锁吗?

问题描述 投票:-1回答:2

我不擅长多线程,并对此代码感到困惑:

public class Main {
    public static void main(String... args) throws Exception {
        new Thread(Main::test).start();
    }

    private static synchronized void test() {
        new Thread(Main::test).start();
        System.out.println("TEST");
    }
}

它会导致死锁吗?如果是这样,那为什么我无法让它陷入僵局?我的想法是,线程1获取对test()的锁定,然后在test()中创建的另一个线程试图获取它并且它们应该在彼此等待。但他们不是,为什么不呢?

我知道,在join()中添加test()会导致死锁,但是下面的示例为什么不使用连接和死锁?

每次运行时,此代码都会导致死锁:

public class Main {
    public static void main(String... args) {
        new Thread(Main::test).start();
        new Thread(Main::test2).start();
    }

    private static void test() {
        synchronized (Integer.class) {
            try {
                Thread.sleep(1);
            } catch (Exception e) {
            }
            synchronized (Float.class) {
                System.out.println("Acquired float");
            }
        }
    }

    private static void test2() {
        synchronized (Float.class) {
            try {
                Thread.sleep(1);
            } catch (Exception e) {
            }
            synchronized (Integer.class) {
                System.out.println("Acquired integer");
            }
        }
    }
}
java multithreading
2个回答
3
投票

不,第一个示例中的代码不能死锁。新启动的线程将一直等到前一个线程退出方法以获取锁定。

第二个示例中的代码死锁,因为锁是以相反的顺序获取的,并且由于睡眠可靠地相互阻塞。


-1
投票

当您处于初次学习如何考虑并发性和相关问题的阶段时,我非常建议使用物理道具来保持您的想法和假设清晰明确。

例如,抓住一张A3纸,设置一个“赛道”,你可以使用Monopoly片段来表示你在代码中做了什么,你期望发生什么,以及你的实验显示实际发生了什么。

当您的实验无法解决时,请先从一小部分开始,然后进行验证。然后再添加一些,依此类推。

如果您了解实际计算机(不是CS理想计算机或概念计算机)当前的工作原理,它会有所帮助。 CPU如何将数据从主内存中取出到其缓存中。两个或三个CPU如何决定哪一个CPU可以一次处理一个缓存行中的数据。然后,Java内存模型如何需要您编写源代码,以便JVM知道您实际意味着发生什么。

© www.soinside.com 2019 - 2024. All rights reserved.