死锁:
在多线程竞争使用共享资源的情况下,就有可能出现死锁的情况。比如,当一个线程等待另一个线程所持有的锁时,那个线程又可能在等待第一个线程所持有的锁。此时,这两个线程会陷入无休止的相互等待状态,这种情况就称为死锁。
产生死锁的四个必要条件:
1、互斥条件。进程对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占有。
2、请求和保持条件。当进程因请求资源而阻塞时,对已获得的资源保持不放。
3、不剥夺条件。进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4、环路等待条件。在发生死锁时,必然存在一个进程-资源的环形链,即进程集合{P1,P2,。。。,Pn}中的P1等待一个P2占用的资源,P2正在等待一个P3占用的资源,。。。,Pn正在等待已被P1所占用的资源。
比较简单的解决死锁的方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。
下面是产生死锁的一个示例:
package com.hh.deadLock; public class DeadLockDemo { public static void main(String[] args) { final Object resource1 = "资源1"; final Object resource2 = "资源2"; Thread t1 = new Thread(){ public void run() { synchronized(resource1){ System.out.println("线程1:获取资源1使用权"); try { Thread.sleep(500); } catch (Exception e) { } synchronized(resource2){ System.out.println("线程1:等待资源2"); } } } }; Thread t2 = new Thread(){ public void run() { synchronized(resource2){ System.out.println("线程2:获取资源2使用权"); try { Thread.sleep(500); } catch (Exception e) { } synchronized(resource1){ System.out.println("线程2:等待资源1"); } } } }; t1.start(); t2.start(); } }
线程1:获取资源1使用权 线程2:获取资源2使用权或者是
线程2:获取资源2使用权 线程1:获取资源1使用权然后程序就不再往下执行
线程t1获取“资源1”使用权后等待“资源2”,而线程t2获取“资源2”使用权后等待“资源1”,这样,线程t1和线程t2就引起了死锁。
如果将程序中的Thread.sleep(500);这行代码注释,则程序可能引起死锁,也可能不引起。
原文地址:http://blog.csdn.net/huhui_cs/article/details/38525831