08 死锁出现的原因以及怎么解决?
出现死锁的原因是因为两个线程出现持有对方想要的资源,导致这两个线程一直处在等待对方释放锁的状态;
破坏竞态条件既可以解除死锁,例如:当一个线程持有锁时,自己没有释放锁时不能再去尝试获取另一个锁;
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package com.local.demo.test.thredtest;
public class DeadThread {
private static final Object lock1 = new Object(); private static final Object lock2 = new Object();
public static void main(String[] args) { Thread thread1 = new Thread(() -> { synchronized (lock1) { System.out.println("Thread 1: Holding lock 1..."); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 1: Waiting for lock 2..."); synchronized (lock2) { System.out.println("Thread 1: Acquired lock 2!"); } } });
Thread thread2 = new Thread(() -> { synchronized (lock2) { System.out.println("Thread 2: Holding lock 2..."); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 2: Waiting for lock 1..."); synchronized (lock1) { System.out.println("Thread 2: Acquired lock 1!"); } } }); thread1.start(); thread2.start();
try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Main thread finished."); } }
|
这里的thread1.join();thread2.join();只是主线程显式调用两个子线程的join方法,让jvm 等待两个子线程执行完成再执行主线程。达到观测的目的,如果不加这两行代码,主线程结束,子线程还会继续跑;除非关闭计算机或者关闭jvm进程;
如何让主线程结束,子线程也终止
1.显示的调用thread1.interrupt方法,让子线程抛出异常,子线程终止。
2.设置子线程thread1.setDaemon(true);改为守护线程,当主线程结束,守护线程也会结束。