Java------多线程_并发_死锁_产生与解决(十一)
死锁:
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情况,某一个同步块同时拥有“二个以上对象的锁”时,就可能会发生死锁的问题。
案例以:两个人化妆,同时想涂口红、照镜子。
锁套锁,就会产生死锁
/**
* 死锁
*/
public class ThreadDeadLock {
public static void main(String[] args) {
Markup markup = new Markup("小红",2);
Markup markup2 = new Markup("小蓝",1);
markup.start();
markup2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class Markup extends Thread{
//静态的表示,只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
//选择
int choice;
//名字
String name;
public Markup(String name,int choice){
this.choice = choice;
this.name = name;
}
@Override
public void run() {
//化妆
try {
markup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//相互持有对方的对象锁---—可能造成死锁
private void markup() throws InterruptedException {
if (choice == 1){
synchronized (lipstick){
System.out.println(this.name+"涂口红");
//1秒后拥有镜子的锁
Thread.sleep(1000);
synchronized (mirror){
System.out.println(this.name+"照镜子");
}
}
}else {
synchronized (mirror){
System.out.println(this.name+"照镜子");
//2秒后想拥有口红的锁
Thread.sleep(2000);
synchronized (lipstick){
System.out.println(this.name+"涂口红");
}
}
}
}
}
避免死锁问题的发生:避免在一个代码块中,同时持有两个或以上的对象。
将内部的锁移出来,改为并列即可解决该问题。
//相互持有对方的对象锁---—可能造成死锁
private void markup() throws InterruptedException {
if (choice == 1){
synchronized (lipstick){
System.out.println(this.name+"涂口红");
}
//1秒后拥有镜子的锁
Thread.sleep(1000);
synchronized (mirror){
System.out.println(this.name+"照镜子");
}
}else {
synchronized (mirror){
System.out.println(this.name+"照镜子");
}
//2秒后想拥有口红的锁
Thread.sleep(2000);
synchronized (lipstick){
System.out.println(this.name+"涂口红");
}
}
}