1 什么是死锁?
死锁 :是指两个或两个以上的进程在执行过程中,去争夺同样的一个共享资源而造成的一种互相等待的现象,若无人工干预,等待线程将永远等待,无法继续执行。
2 发生死锁的条件是什么?
1 互斥条件: 一个资源每次只能被一个进程使用。
2 请求与保持条件: 一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3 不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。
4 循环等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系。
3 如何避免死锁?
若已经造成了死锁:只有破环四个必要条件的其中一个就行
若还未造成死锁:
设计原则;在系统设计、进程调度等方面注意如何不让这四个必要条件成立。
1 避免嵌套锁:当我们为多个线程提供锁时,主要会发生死锁。如果我们已经给一个线程,请避免给多个线程加锁。
2 尽量使用同步代码快 而不是同步方法:同步方法是把整个方法给加上锁给同步了, 范围较大,造成性能低下, 使用同步代码块范围小,性能高。使用同步代码块, 可以自己指定锁的对象, 这样有了锁的控制权, 这样也能避免发生死锁
3 对资源的分配要给予合理的规划;如确定资源的合理分配算法,避免进程永久占据系统资源,防止进程在处于等待状态的情况下占用资源。
4 死锁代码简单实现
public class DeadLock { public static void main(String[] args) { Object o1 = new Object(); Object o2 = new Object(); threadTest1 t1 = new threadTest1(o1,o2); threadTest1 t2 = new threadTest1(o1,o2); t1.setName("t1"); t2.setName("t2"); t1.start(); t2.start(); } } class threadTest1 extends Thread{ Object o1; Object o2; public threadTest1(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } public threadTest1() { } @Override public void run() { synchronized (o1) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o2) { //System.out.println(Thread.currentThread().getName()+"能被输出吗?"); } } } } class threadTest2 extends Thread{ Object o1; Object o2; public threadTest2(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } public threadTest2() { } @Override public void run() { synchronized (o2) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o1) { //System.out.println(Thread.currentThread().getName()+"能被输出吗?"); } } } }
5 死锁关键代码:
Synchorized(objectA){ Synchorized(objectB){ } } Synchorized(objectB){ Synchorized(objectA){ } }