死锁及解决方案
死锁”指的是:
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。
因此, 某一个同步块需要同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。下面案例中,“化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。那么,实际运行时,“小丫的化妆线程”拥有了“镜子对象”,“大丫的化妆线程”拥有了“口红对象”,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的“死锁状态”。
死锁问题演示
class Lipstick {//口红类
}
class Mirror {//镜子类
}
class Makeup extends Thread {//化妆类继承了Thread类
int flag;
String girl;
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
@Override
public void run() {
// TODO Auto-generated method stub
doMakeup();
}
void doMakeup() {
if (flag == 0) {
synchronized (lipstick) {//需要得到口红的“锁”;
System.out.println(girl + "拿着口红!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mirror) {//需要得到镜子的“锁”;
System.out.println(girl + "拿着镜子!");
}
}
} else {
synchronized (mirror) {
System.out.println(girl + "拿着镜子!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lipstick) {
System.out.println(girl + "拿着口红!");
}
}
}
}
}
public class TestDeadLock {
public static void main(String[] args) {
Makeup m1 = new Makeup();//大丫的化妆线程;
m1.girl = "大丫";
m1.flag = 0;
Makeup m2 = new Makeup();//小丫的化妆线程;
m2.girl = "小丫";
m2.flag = 1;
m1.start();
m2.start();
}
}
锁套锁 导致需要同时拿到两个锁才能继续线程,而另一个线程已经把镜子锁提前拿到了,所以会导致死锁
死锁问题的解决
class Lipstick {//口红类
}
class Mirror {//镜子类
}
class Makeup extends Thread {//化妆类继承了Thread类
int flag;
String girl;
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
@Override
public void run() {
// TODO Auto-generated method stub
doMakeup();
}
void doMakeup() {
if (flag == 0) {
synchronized (lipstick) {
System.out.println(girl + "拿着口红!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (mirror) {
System.out.println(girl + "拿着镜子!");
}
} else {
synchronized (mirror) {
System.out.println(girl + "拿着镜子!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (lipstick) {
System.out.println(girl + "拿着口红!");
}
}
}
}
public class TestDeadLock {
public static void main(String[] args) {
Makeup m1 = new Makeup();// 大丫的化妆线程;
m1.girl = "大丫";
m1.flag = 0;
Makeup m2 = new Makeup();// 小丫的化妆线程;
m2.girl = "小丫";
m2.flag = 1;
m1.start();
m2.start();
}
}
不要锁套锁,将第二个锁放到第一个锁的代码块外,这样第一个对象拿到口红锁后,用完了然后sleep,第二个对象也用完了和口红锁,这样就能解决死锁