Java多线程死锁状态典例及解决方案

2022-07-30 11:27:54


1.死锁的定义

     所谓死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。 简单地讲,死锁时过多的同步可能造成相互不是放资源的现象。

2.那么产生死锁的原因是什么

     导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性访问权。

3.举个简单的例子

两位女孩,小a占用着口红,持有口红的锁;小c占用着镜子,持有镜子的锁,这个时候,小a想要镜子,小c却想要口红,但小a和小c却相互不释放,两人互相等待对方松开锁。就这样,局面僵持了。。。就死锁了

public class DeadLock{
	public static void main(String[] args) {
		Markup g1 = new Markup(0, "小a");
		Markup g2 = new Markup(1, "小c");
		g1.start();
		g2.start();
	}
}

//口红
class Lipstick{
	
}

//镜子
class Mirror{
	
}

//化妆
class Markup extends Thread{
	static Lipstick lipstick = new Lipstick();
	static Mirror mirror = new Mirror();
	int choice;//选择,0为口红,1为镜子
	String girl;
	public Markup(int choice, String girl) {
		this.choice = choice;
		this.girl = girl;
	}
	
	public void run() {
		markup();
	}
	
	private void markup() {
		if(choice==0) {
			synchronized(lipstick) {
				System.out.println(this.girl+"涂口红");
				try {
					Thread.sleep(1000);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(mirror) {
					System.out.println(this.girl+"照镜子");
				}
			}
		}else {
			synchronized(mirror) {
				System.out.println(this.girl+"照镜子");
				try {
					Thread.sleep(1000);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(lipstick) {
					System.out.println(this.girl+"涂口红");
				}
			}
		}
	}
}

运行结果:

小a涂口红
小c照镜子

4.如何避免死锁

注意不要在同一个代码块中,同时持有多个对象的锁。下面代码对上面例子做简单修改。把第二次的synchronized代码块从第一次的synchronized代码块中移了出来,避免了锁套锁,这样就可以避免死锁了。

public class DeadLock {
	public static void main(String[] args) {
		Markup g1 = new Markup(0, "小a");
		Markup g2 = new Markup(1, "小c");
		g1.start();
		g2.start();
	}
}

class Lipstick{
	
}

class Mirror{
	
}

class Markup extends Thread{
	static Lipstick lipstick = new Lipstick();
	static Mirror mirror = new Mirror();
	int choice;
	String girl;
	public Markup(int choice, String girl) {
		this.choice = choice;
		this.girl = girl;
	}
	
	public void run() {
		markup();
	}
	
	public void markup() {
		if(choice==0) {
			synchronized(lipstick) {
				System.out.println(this.girl+"涂口红");
				try {
					Thread.sleep(1000);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
			synchronized(mirror) {
				System.out.println(this.girl+"照镜子");
			}
		}else {
			synchronized(mirror) {
				System.out.println(this.girl+"照镜子");
				try {
					Thread.sleep(1000);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
			synchronized(lipstick) {
				System.out.println(this.girl+"涂口红");
			}
		}
	}
}

运行结果:

小a涂口红
小c照镜子
小c涂口红
小a照镜子

这样修改后的程序就不会进入死锁状态了,谢谢浏览。。。

  • 作者:zihan_2024
  • 原文链接:https://blog.csdn.net/qq_40639828/article/details/88079191
    更新时间:2022-07-30 11:27:54