线程死锁

面试题,请写一个线程死锁的代码。

首先需要明白什么是死锁?

死锁,是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力作用,它们将无法推进下去,此时称系统处于死锁状态或系统产生了死锁。

常见产生死锁的原因有哪些?

系统资源不足;进程运行顺序不合适;资源分配不相等;进程运行速度不同也可能产生死锁(类似于执行顺序)。

产生死锁的四个必要条件?这四个条件其实在对死锁的定义进行解释。

1)互斥条件,一个资源每次只能被一个进程使用;(两个或两个以上进程执行)

2)请求与保持条件,一个进程请求资源阻塞时,对获得的资源保持占用,不释放(因争夺资源而造成的一种相互等待的现象)

3)不解除资源占用;这里其实指无外力作用;在资源未使用完之前,无外力强制解除资源占用(若无外力作用,它们将无法推进下去)

4)循环等待条件,若干进程直接形成一种头尾相接的循环等待资源关系。(相互等待的现象)

这四个必要条件,有一个条件不成立,就不能形成死锁。

上面说清楚了定义,条件,那么代码只需要根据条件来编写。如下,是我写的一个线程死锁的Demo

package mytest;

public class TestThreadDeadLock { //定义一个死锁类
	//死锁满足四个条件;1,互斥条件;2,请求和保持资源占用;3,无外力不解除占用;4,相互引用循环等待
	
	//1,互斥,来两个类ThreadA,ThreadB
	//2,资源占用,来写一个资源source数组
	static String[] source = new String[] {"资源1","资源2"};
	
	static class ThreadA implements Runnable{

		@Override
		public void run() {
			synchronized(source[0]) {//请求资源并保持资源占用资源1
				System.out.println("ThreadA在使用资源:"+source[0]);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(source[1]) {//去请求使用资源2;而此时另一个线程ThreadB在使用资源2;
					System.out.println("ThreadA将要使用资源:"+source[1]);
				}
			}
		}
		
	}
	
	static class ThreadB implements Runnable{

		@Override
		public void run() {
			synchronized(source[1]) {//请求资源并保持资源占用资源2
				System.out.println("ThreadB在使用资源:"+source[1]);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(source[0]) {//此时另一个线程ThreadA,在占用资源1;
					System.out.println("ThreadA将要使用资源:"+source[0]);
				}
			}
		}
	}
	
	public static void main(String args[]) {
		ThreadA a = new ThreadA();
		ThreadB b = new ThreadB();
		new Thread(a).start();
		new Thread(b).start();
		//线程同时启动,资源被相互占用,又相互循环,无外力能强制解除资源占用。此时,造成死锁。
		
		//不要怀疑是程序卡住了。写个守护线程验证一下
		DaemondThread daemond = new DaemondThread();
		daemond.start();
	}
	
	static class DaemondThread extends Thread{//线程的两种方式,继承Thread,或实现Runnable
		public void run() {
			while(true) {
				System.out.println("守护线程执行中。。。");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}

下面是运行结果

从结果可以看到,ThreadA和ThreadB都占用了一个资源,在等待彼此使用完另外一个资源释放;这样就在资源相互请求和资源占用过程中,又无外力强制释放资源,而使程序形成了死锁。

 

多说一句;如何解除死锁呢?

只需要破坏四个条件中的一个,便可以解除死锁。如上面代码,如何解除呢?

只需要将两个线程占用资源的顺序改为一样的,便可解除死锁。如下图:

死锁讨论至此结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值