死锁产生的原因以及手写死锁

系统管理员 2023-07-20 12:28 57阅读 0赞
产生死锁的原因可归结为如下两点:

a. 竞争资源

系统中的资源可以分为两类:

  1. 可剥夺资源,是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺
  2. 不可剥夺资源,当系统把这类资源分配给某进程后,只能等进程用完后自行释放

产生死锁中的竞争资源之一指的是竞争不可剥夺资源
产生死锁中的竞争资源另外一种资源指的是竞争临时资源,通常消息通信顺序进行不当,则会产生死锁

b. 进程间推进顺序非法

若P1保持了资源R1,P2保持了资源R2,当P1需要继续占用R2且需要占用R1时两个线程均被阻塞,于是发生进程死锁

死锁产生的4个必要条件:
  1. 互斥条件:进程要求对所分配的资源进行排它性控制
  2. 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放
  3. 不剥夺条件:进程已获得的资源在未使用完之前,只能在使用完时由自己释放
  4. 环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。
手写死锁
  1. public class DeadLock {
  2. public static void main(String... args) {
  3. Thread t1 = new Thread(new MyDeadLock(true));
  4. Thread t2 = new Thread(new MyDeadLock(false));
  5. t1.start();
  6. t2.start();
  7. }
  8. }
  9. class MyDeadLock implements Runnable {
  10. private boolean flag;
  11. // 使用static为静态变量, 内存在方法区中,
  12. // 方法区中的对象是线程共享的,所以会引发死锁
  13. // 不加static存在堆上
  14. // 堆上的对象是线程私有的, 下面的写法就不会造成死锁
  15. private static Object o1 = new Object();
  16. private static Object o2 = new Object();
  17. public MyDeadLock(boolean flag) {
  18. this.flag = flag;
  19. }
  20. @Override
  21. public void run() {
  22. if (this.flag) {
  23. synchronized (o1) {
  24. try {
  25. Thread.sleep(1000);
  26. } catch (InterruptedException e) {
  27. System.out.println("e.printStackTrace();");
  28. }
  29. synchronized (o2) {
  30. System.out.println("嘿嘿嘿");
  31. }
  32. }
  33. } else {
  34. synchronized (o2) {
  35. try {
  36. Thread.sleep(1000);
  37. } catch (InterruptedException e) {
  38. System.out.println("e.printStackTrace();");
  39. }
  40. synchronized (o1) {
  41. System.out.println("哈哈哈");
  42. }
  43. }
  44. }
  45. }
  46. }

其他写法

  1. import java.security.PublicKey;
  2. public class DeadLock1 {
  3. public static void main(String... args) {
  4. Object o1 = new Object();
  5. Object o2 = new Object();
  6. Thread t1 = new Thread(new MyDeadLock1(true, o1, o2));
  7. Thread t2 = new Thread(new MyDeadLock1(false, o1, o2));
  8. t1.start();
  9. t2.start();
  10. }
  11. }
  12. class MyDeadLock1 implements Runnable {
  13. private boolean flag;
  14. private Object o1;
  15. private Object o2;
  16. public MyDeadLock1(boolean flag, Object o1, Object o2) {
  17. this.flag = flag;
  18. this.o1 = o1;
  19. this.o2 = o2;
  20. }
  21. @Override
  22. public void run() {
  23. if (this.flag) {
  24. synchronized (o1) {
  25. try {
  26. Thread.sleep(1000);
  27. } catch (InterruptedException e) {
  28. System.out.println("e.printStackTrace();");
  29. }
  30. synchronized (o2) {
  31. System.out.println("嘿嘿嘿");
  32. }
  33. }
  34. } else {
  35. synchronized (o2) {
  36. try {
  37. Thread.sleep(1000);
  38. } catch (InterruptedException e) {
  39. System.out.println("e.printStackTrace();");
  40. }
  41. synchronized (o1) {
  42. System.out.println("哈哈哈");
  43. }
  44. }
  45. }
  46. }
  47. }

发表评论

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

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

相关阅读