内容:一个简单的死锁例子,大概的思路:两个线程A和B,两把锁X和Y,现在A先拿到锁X,然后sleep()一段时间,我们知道sleep()是不会释放锁资源的。然后如果这段时间线程B拿到锁Y,也sleep()一段时间的话,那么等到两个线程都醒过来的话,那么将互相等待对方释放锁资源而僵持下去,陷入死锁。flag的作用就是让A和B获得不同的锁。
写多线程的程序的时候要避免产生死锁,那我们首先要知道怎么会产生死锁才能预防死锁。接下来用java写一个会产生死锁的程序。
新建一个类DeadLock
public class DeadLock implments Runnable{
public boolean flag;
public Object o1 = new Object();
public Object o2 = new Object();
private DeadLock(boolean flag){
this.flag = flag;//在构造方法里输入一个状态
}
@Override
public void run(){
if(this.flag){
synchronized(o1){
try{
Thread.sleep(1000);//在第一个线程锁住o1对象时睡眠1秒,那么这一秒内是线程占着o1
}catch(Exception e){
e.printStackTrace();
}
synchronized(o2){
System.out.println("01 is ok");
}
}else{
synchronized(o2){
try{
Thread.sleep(100);//线程o2锁住o2,那么前0.1秒内是o2占着o2,在0.1秒后,线程2请求o1而此时o1被线程1占着
//所以o2等待o1的结果。1秒后,线程请求o2,而o2被线程2占着,那么线程1又要等待线程2的结果,于是他们互相等待就产生
//死锁了
}catch(Exception e){
e.printStackTrace();
}
synchronized(o1){
System.out.println("02 is ok");
}
}
}
}
//编写测试类
public class TestDeadLock{
public static void main(String[] args){
Thread t1 = new Thread(new DeadLock(true));
Thread t2 = new Thread(new DeadLock(false));
t1.start();
t2.start();
}
}
所以写死锁最主要的是创建一个线程互相等待结果的状态,最简单的就是在一个线程锁住一个对象1的时候去请求对象2,而第二个线程在锁住对象2的同时去请求对象1,就ok了。
public class TestDeadLock {
public void run() {
MyThread mt = new MyThread();
new Thread(mt, "张三").start();
new Thread(mt, "李四").start();
}
class MyThread implements Runnable {
private Object o1 = new Object();
private Object o2 = new Object();
private boolean flag = true;
@Override
public void run() {
if (flag) {
flag = false;
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + " have o1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + " have o2");
}
}
} else {
flag = true;
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + " have o2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + " have o1");
}
}
}
}
}
public static void main(String[] args) {
new TestDeadLock().run();
}
}