Java多线程同步问题探讨:死锁示例

原创 电玩女神 2024-09-12 08:27 189阅读 0赞

死锁在多线程编程中是一种常见的问题,如果设计不当,多个线程可能会因为互相等待对方释放资源而陷入无法继续执行的境地。

下面是一个简单的Java多线程死锁示例:

  1. // 线程1,想要获取资源A
  2. class Thread1 implements Runnable {
  3. private int resourceA;
  4. public Thread1(int resourceA) {
  5. this.resourceA = resourceA;
  6. }
  7. @Override
  8. public void run() {
  9. try {
  10. // 获取资源A后,会尝试获取资源B
  11. synchronized (resourceA) { // 这里使用了Java的synchronized关键字
  12. if (resourceB != null && !resourceB.isFree()) { // 如果资源B已经被其他线程占用
  13. System.out.println("Thread1 waiting for resource B to be free...");
  14. resourceA.wait(); // 等待资源A释放锁,让出执行权
  15. } else {
  16. System.out.println("Thread1 acquiring resource A...");
  17. resourceA.acquire(); // 获取锁
  18. if (resourceB != null && !resourceB.isFree()) { // 如果资源B已经被其他线程占用
  19. System.out.println("Thread1 waiting for resource B to be free...");
  20. resourceB.wait(); // 等待资源B释放锁,让出执行权
  21. } else {
  22. System.out.println("Thread1 acquiring resource B...");
  23. resourceB.acquire(); // 获取锁
  24. }
  25. }
  26. }
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }
  32. // 线程2,想要获取资源B
  33. class Thread2 implements Runnable {
  34. private int resourceB;
  35. public Thread2(int resourceB) {
  36. this.resourceB = resourceB;
  37. }
  38. @Override
  39. public void run() {
  40. try {
  41. // 获取资源B后,会尝试获取资源A
  42. synchronized (resourceB) { // 这里使用了Java的synchronized关键字
  43. if (resourceA != null && !resourceA.isFree()) { // 如果资源A已经被其他线程占用
  44. System.out.println("Thread2 waiting for resource A to be free...");
  45. resourceA.wait(); // 等待资源A释放锁,让出执行权
  46. } else {
  47. System.out.println("Thread2 acquiring resource B...");
  48. resourceB.acquire(); // 获取锁
  49. if (resourceA != null && !resourceA.isFree()) { // 如果资源A已经被其他线程占用
  50. System.out.println("Thread2 waiting for resource A to be free...");
  51. resourceA.wait(); // 等待资源A释放锁,让出执行权
  52. } else {
  53. System.out.println("Thread2 acquiring resource A...");
  54. resourceA.acquire(); // 获取锁
  55. if (resourceB != null && !resourceB.isFree()) { // 如果资源B已经被其他线程占用
  56. System.out.println("Thread2 waiting for resource B to be free...");
  57. resourceB.wait(); // 等待资源B释放锁,让出执行权
  58. } else {
  59. System.out.println("Thread2 acquiring resource B...");
  60. resourceB.acquire(); // 获取锁
  61. }
  62. }
  63. }
  64. }
  65. } catch (InterruptedException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. // 主程序启动两个线程并等待其结束
  71. public static void main(String[] args) {
  72. Thread1 thread1 = new Thread1(0); // 创建一个资源A值为0的Thread1实例
  73. Thread2 thread2 = new Thread2(1); // 创建一个资源B值为1的Thread2实例
  74. thread1.start(); // 启动线程1
  75. thread2.start(); // 启动线程2
  76. try {
  77. thread1.join(); // 等待线程1结束
  78. thread2.join(); // 等待线程2结束
  79. } catch (InterruptedException e) {
  80. e.printStackTrace();
  81. }
  82. System.out.println("Both threads have completed and resources are released."); // 打印消息,表示两个线程已经完成并释放了资源
  83. }

在这个示例中,两个线程Thread1Thread2分别尝试获取两个资源resourceAresourceB。由于互斥的性质,一个资源在被任何线程占用时,其他线程必须等待其释放。

Thread1获得resourceA后,它会等待resourceB释放锁;而Thread2的情况类似,它会等待resourceA释放锁。

最终,如果所有资源都被正确地顺序获取和释放,那么死锁就不会发生。在上述示例中,如果没有意外,程序应该能够正常运行并完成任务。

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

发表评论

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

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

相关阅读

    相关 Java线同步示例

    在Java多线程编程中,死锁是一种常见的并发问题。当两个或更多的线程相互等待对方释放资源时,就会发生死锁。 以下是一个简单的Java死锁示例: ```java // 创建两

    相关 Java线同步问题示例

    Java中的死锁是指两个或多个线程在执行过程中,因争夺资源而造成的一种僵局,导致这些线程无法继续执行下去。死锁发生时,每个线程都在等待其他线程释放资源,但因为没有线程愿意释放资