第8行或第16行是如何发生死锁的?
1. public class DeadlockRisk {
2. private static class Resource {
3. public int value;
4. }
5. private Resource resourceA = new Resource();
6. private Resource resourceB = new Resource();
7. public int read() {
8. synchronized(resourceA) {
9. synchronized(resourceB) {
10. return resourceB.value + resourceA.value;
11. }
12. }
13. }
14
15. public void write(int a, int b) {
16. synchronized(resourceB) {
17. synchronized(resourceA) {
18. resourceA.value = a;
19. resourceB.value = b;
20. }
21. }
22. }
23. }
答案 0 :(得分:5)
可能发生死锁,因为锁定顺序不一致,这意味着一个线程可以获取resourceA
并等待resourceB
而另一个线程已获得resourceB
但正在等待{{1} }}。例如:
resourceA
,成功获取read()
,然后暂停。resourceA
,成功获取write()
并等待resourceB
。resourceA
(resourceB
永远不会释放)。 T2
或T1
都无法进展,因为每个人都在等待另一个已锁定的资源。始终拥有一致的锁定顺序:
T2
(但是,在发布的代码中似乎没有理由拥有多个锁,因为总是获取两个锁。)
答案 1 :(得分:0)
读取将resourceA作为外部锁的一部分。写获取资源B.这发生在任一线程锁定内部锁的对象之前。
要继续,read需要resourceB,但write已经有了resourceB。写入可以在获得resourceA后立即释放资源B,但读取具有resourceA,并且在给予resourceB之前无法放弃它。
作为一般提示,在锁定多个对象时使用一致的顺序。两者中的A和B,或两者中的B和A。