“死锁”指的是:
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。
某一个同步块需要同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。
比如,“化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。那么,实际运行时,“小丫的化妆线程”拥有了“镜子对象”,“大丫的化妆线程”拥有了“口红对象”,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的“死锁状态”。
下面是案例的代码演示
/**
* 口红类
*/
class Lipstick{
}
/**
* 镜子类
*/
class Mirror{
}
/**
* 化妆线程类
*/
class Makeup extends Thread{
private int flag; //flag=0:拿着口红。flag!=0:拿着镜子
private String girlName;
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
public Makeup(int flag,String girlName){
this.flag = flag;
this.girlName = girlName;
}
@Override
public void run() {
this.doMakeup();
}
/**
* 开始化妆
*/
public void doMakeup(){
if(flag == 0){
synchronized (lipstick){
System.out.println(this.girlName+" 拿着口红");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mirror){
System.out.println(this.girlName+" 拿着镜子");
}
}
}else{
synchronized (mirror){
System.out.println(this.girlName+" 拿着镜子");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lipstick){
System.out.println(this.girlName+" 拿着口红");
}
}
}
}
}
public class DeadLockThread {
public static void main(String[] args) {
new Makeup(0,"大丫").start();
new Makeup(1,"小丫").start();
}
}
上市代码会出现一直运行无法结束的状态,解决方法即是不能做synchronized嵌套,改动如下:
注意synchronized的位置变化:
/**
* 口红类
*/
class Lipstick{
}
/**
* 镜子类
*/
class Mirror{
}
/**
* 化妆线程类
*/
class Makeup extends Thread{
private int flag; //flag=0:拿着口红。flag!=0:拿着镜子
private String girlName;
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
public Makeup(int flag,String girlName){
this.flag = flag;
this.girlName = girlName;
}
@Override
public void run() {
this.doMakeup();
}
/**
* 开始化妆
*/
public void doMakeup(){
if(flag == 0){
synchronized (lipstick){
System.out.println(this.girlName+" 拿着口红");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (mirror){
System.out.println(this.girlName+" 拿着镜子");
}
}else{
synchronized (mirror){
System.out.println(this.girlName+" 拿着镜子");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (lipstick){
System.out.println(this.girlName+" 拿着口红");
}
}
}
}
public class DeadLockThread {
public static void main(String[] args) {
new Makeup(0,"大丫").start();
new Makeup(1,"小丫").start();
}
}
经过修改后代码正常运行。