java中的信号量和死锁

时间:2015-12-13 13:11:33

标签: java operating-system

我正在尝试了解信号量和死锁,我偶然发现了这一点。任何人都可以给我一个提示吗?任何东西。谢谢。

以下代码中的方法threadA()和threadB()在两个分离的线程中启动。是否存在导致死锁的任何指令序列?如果是,请给一个。

class ClassOne {
    static Semaphore lock1 = new Semaphore (1);
    static Semaphore lock2 = new Semaphore (1);

    void treadA(){
       lock1.acquire();
       //critical section
       lock1.release();
    }

    void threadB(){
       lock1.acquire();
       lock2.acquire();
       //critical section
       lock2.release();
       lock1.release();
    }
}

第二个代码的相同问题:

class ClassTwo {
    static Semaphore lock1 = new Semaphore(1); 
    static Semaphore lock2 = new Semaphore(1);

    void threadA(){
        lock1 . acquire (); 
        lock2 . acquire ();
        //critical section
        lock2 . release (); 
        lock1 . release ();
    }

    void threadB() { 
        lock2 . acquire (); 
        lock1 . acquire ();
        //critical section 
        lock1 . release (); 
        lock2 . release ();
    } 
}     

4 个答案:

答案 0 :(得分:0)

当有可能在不同的线程中以相反的顺序获取锁定时,会发生死锁。正如您在第二个示例中所看到的,在diff线程中的opp seq中会进行锁定,因此存在死锁的可能性。但是在第一个例子中,锁定采用相同的顺序,因此它不会出现死锁

答案 1 :(得分:0)

第二个代码段似乎有误,因为你有多个锁,但你不会在每个地方以相同的顺序使用它们。您可能会遇到以下死锁:

   threadA aquires lock1
   threadB aquires lock2
   threadA block on lock2
   threadB locks on lock1
  => deadlock

你可能会发现很多或者引用文章,因为它是多线程上下文中众所周知的死锁源(无论你使用哪种语言);您可以查看此https://books.google.fr/books?id=2hYqeoO8t8IC&pg=PA72&lpg=PA72#v=onepage&q&f=false

答案 2 :(得分:0)

在第一个样本中,没有。没有死锁是可能的。 在第二个,是的:

  1. threadA获取lock1,然后VM将控制权转移到threadB
  2. threadB获得lock2
  3. 完成!
  4. 在这种情况下,避免互锁的最简单方法是为每个锁分配一个序号(您已经通过命名lock1lock2来完成此操作);然后对线程进行编码,以便它们始终按升序获取锁。更确切地说,如果拥有更高编号的锁,则没有线程尝试获取锁(在第二个示例中,只需反转acquire中的threadB次调用。

    如果由于某种原因,某个帖子需要在比lock2更早的时间内获取lock1(因此保持lock1的所有权不可行很长一段时间,当它不是真正需要的时候,有一些可能会有所帮助的策略:

    • 重新编号锁,以便顺序方便线程。
    • 当线程需要获取lock1时,首先发布lock2,然后获取lock1,然后再次获取lock2

    采用这种策略,不可能实现互锁。为了证明这一点,选择最高编号的非自由锁(即它由一个线程拥有)。拥有此锁的线程始终可以继续,因为它不需要任何编号较低的锁,所有编号较高的锁都是空闲的。

答案 3 :(得分:0)

Cheeky Hudds Uni学生试图通过他们的操作系统任务获得免费通行证;)