有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java死锁涉及多少线程

我正试图找出一个面试问题的答案 死锁涉及多少线程

我回答应该是两个或更多,但面试官说这是一个错误的答案

我试着在网上搜索,但不明白为什么我的答案是错的


共 (4) 个答案

  1. # 1 楼答案

    答案是,这取决于锁或锁定机制的类型

    • 对于可重入锁,需要两个或更多线程。(请注意,Java基本锁/互斥锁是可重入的)

    • 对于不可重入锁,单个线程可以通过尝试获取其已持有的锁来实现自身死锁

    线程也可能以其他方式阻塞自己,而这些方式实际上与死锁2无法区分。例如:

        Thread.currentThread().join();
    

    通过让线程等待完成来阻止线程。在引擎盖下,join()调用正在等待一个永远不会发生的通知/条件。你可以自己明确地做同样的事情;e、 g

        Object lock = new Object();  // local variable
        synchronized (lock) {
            lock.wait();
        }
    

    1-这取决于锁的精确语义。例如,在这种情况下,可以实现一个不可重入锁来抛出异常,而不是死锁

    2-这是否真的是死锁取决于您对术语“死锁”的精确定义。在面试中就术语进行争论是不明智的

  2. # 2 楼答案

    如果一个线程试图获取它已经拥有的资源,它可能会死锁。设想一个线程持有一个数据库锁,然后切换到另一个事务(不提交第一个事务),并尝试再次获得相同的锁

  3. # 3 楼答案

    显而易见的答案是“两个或更多”,因为可能会有一系列依赖关系导致死锁

    1 locks A
    2 locks B
    3 locks C
    3 requests A
    2 requests C
    1 requests B
    

    如果要检查被锁定的资源不是由线程“拥有”的,而是由另一个资源“拥有”的情况,它们可能意味着“一个或多个”

    如果资源的拥有对象不是线程,那么需要多次出现拥有对象而不是线程才能导致死锁。在上述示例中,1、2和;3.拥有资源而不是线程

    您可以考虑各种情况,其中一个资源(a)也锁定资源(B),然后同一个线程请求资源(B),但无法获得它。然而,我真的不认为使用“死锁”这个词是有帮助的

  4. # 4 楼答案

    至少在Java中,线程看起来无法锁定自身(就像在递归中);但另一条线可以;所以答案必须是,必须有两条线;下面是一个例子:

    package threadLockTest;
    
    public class ThreadLocking {
    
    private Object LOCK = new Object();
    
    public void recursionWithSynchronization (int count) {
        System.out.println("inside recursionWithSynchronization: count: " + count);
        synchronized (LOCK) {
            if (count == 10) {
                return;
            } else {
                try {
                    Thread.sleep(500);
                    recursionWithSynchronization((count+1));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    
    public static void main (String... args) {
        System.out.println("starting Main thread");
        ThreadLocking stli = new ThreadLocking();
        Runnable ry = () -> {
            System.out.println("starting thread");
            stli.recursionWithSynchronization(1);
            System.out.println("ending thread");
        };
        Thread t1 = new Thread(ry);
        Thread t2 = new Thread(ry);
        t1.start();
        t2.start();
        System.out.println("ending Main thread");
    }
    
    
    }