一个死锁的例子
死锁:
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
死锁的四个必要条件:
互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
避免死锁
a、按同一顺序访问对象。
b、避免事务中的用户交互。
c、保持事务简短并处于一个批处理中。
d、使用较低的隔离级别。
一个死锁的例子:
package ArtOfjavaConcurrency;
/**
* @author zd
*/
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
private void deadLock() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A) {
try {
System.out.println("1");
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.println("11");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B) {
System.out.println("21");
synchronized (A) {
System.out.println("22");
}
}
}
});
t1.start();
t2.start();
}
}
第二个死锁的例子:
class DeadLockTask implements Runnable{
private Object locka = new Object();
private Object lockb = new Object();
public boolean flag = true;
@Override
public void run() {
if(flag){
while(true){
synchronized (locka) {
System.out.println("if .... locka");//同步嵌套情况,如果此时t1持locka运行至此,而t2持lockb运行至下处,那么就会出现争夺锁(资源)的情况,就会产生死锁。
synchronized (lockb) {
System.out.println("if .... lockb");
}
}
}
}else{
while(true){
synchronized (lockb) {
System.out.println("else .... lockb");//t2持lockb运行至此;
synchronized (locka) {
System.out.println("else .... locka");
}
}
}
}
}
}
public class DeadLockDemo {
public static void main(String[] args) throws InterruptedException {
DeadLockTask dlt = new DeadLockTask();
Thread t1= new Thread(dlt);
Thread t2= new Thread(dlt);
// 启动线程
t1.start();
// t1是启动了,但是并不能马上运行,t1进不去if模块,为了让t1执行,进入if模块,我们必须让main线程睡眠一会
Thread.sleep(1);
// 修改标记,让t2进入else模块,让他们进入不同的模块,才会出现争夺资源的情况。
dlt.flag = false;
t2.start();
}
}