我正在尝试了解信号量和死锁,我偶然发现了这一点。任何人都可以给我一个提示吗?任何东西。谢谢。
以下代码中的方法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 ();
}
}
答案 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)
在第一个样本中,没有。没有死锁是可能的。 在第二个,是的:
threadA
获取lock1
,然后VM将控制权转移到threadB
。threadB
获得lock2
。在这种情况下,避免互锁的最简单方法是为每个锁分配一个序号(您已经通过命名lock1
和lock2
来完成此操作);然后对线程进行编码,以便它们始终按升序获取锁。更确切地说,如果拥有更高编号的锁,则没有线程尝试获取锁(在第二个示例中,只需反转acquire
中的threadB
次调用。
如果由于某种原因,某个帖子需要在比lock2
更早的时间内获取lock1
(因此保持lock1
的所有权不可行很长一段时间,当它不是真正需要的时候,有一些可能会有所帮助的策略:
lock1
时,首先发布lock2
,然后获取lock1
,然后再次获取lock2
。采用这种策略,不可能实现互锁。为了证明这一点,选择最高编号的非自由锁(即它由一个线程拥有)。拥有此锁的线程始终可以继续,因为它不需要任何编号较低的锁,所有编号较高的锁都是空闲的。
答案 3 :(得分:0)
Cheeky Hudds Uni学生试图通过他们的操作系统任务获得免费通行证;)