Java并发编程:理解和避免死锁问题实例

原创 骑猪看日落 2024-09-10 13:06 160阅读 0赞

在Java并发编程中,死锁是一个常见的并行问题。它发生在两个或更多的线程互相等待对方释放资源的情况下。

以下是一个简单的例子来理解死锁:

  1. // 线程1拥有资源A和B
  2. public class Thread1 extends Thread {
  3. private ResourceA a;
  4. private ResourceB b;
  5. public Thread1(ResourceA a, ResourceB b) {
  6. this.a = a;
  7. this.b = b;
  8. }
  9. @Override
  10. public void run() {
  11. System.out.println("Thread 1 started");
  12. // 线程等待资源B,而线程1拥有资源B
  13. while (!b.isAvailable()) {
  14. try {
  15. Thread.sleep(100); // 模拟线程等待
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. System.out.println("Thread 1 acquired resource B");
  21. // 线程继续等待资源A,而线程1拥有资源A
  22. while (!a.isAvailable()) {
  23. try {
  24. Thread.sleep(200); // 模拟线程等待
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. System.out.println("Thread 1 acquired resource A");
  30. // 此时,两个线程都拥有了所有的资源,死锁发生
  31. }
  32. }
  33. // 线程2拥有资源B和C
  34. public class Thread2 extends Thread {
  35. private ResourceB b;
  36. private ResourceC c;
  37. public Thread2(ResourceB b, ResourceC c) {
  38. this.b = b;
  39. this.c = c;
  40. }
  41. @Override
  42. public void run() {
  43. System.out.println("Thread 2 started");
  44. // 线程等待资源A,而线程2拥有资源A
  45. while (!b.isAvailable()) {
  46. try {
  47. Thread.sleep(300); // 模拟线程等待
  48. } catch (InterruptedException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. System.out.println("Thread 2 acquired resource A");
  53. // 线程继续等待资源C,而线程2拥有资源C
  54. while (!c.isAvailable()) {
  55. try {
  56. Thread.sleep(400); // 模拟线程等待
  57. } catch (InterruptedException e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. System.out.println("Thread 2 acquired resource C");
  62. // 此时,两个线程都拥有了所有的资源,死锁发生
  63. }
  64. }

在上述例子中,线程1持有资源A和B,线程2持有资源B和C。它们互相等待对方释放资源。

当线程1获取到资源B后,它继续等待资源A,而此时线程2已经拥有资源A。这就形成了一个死锁:两个线程都因对方占有资源而无法继续执行。

文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。

发表评论

表情:
评论列表 (有 0 条评论,160人围观)

还没有评论,来说两句吧...

相关阅读