多线程死锁--画家和作家

前言

若开启多线程,操作同一资源会导致多个线程抢夺执行时间而导致资源出现错误,为解决这一问题我们通常会为线程加锁。但加锁之后也会导致线程进入死锁状态。

一、什么是线程死锁

我们用画家和作家的例子来剖析线程死锁,画家和作家都需要同时拿到纸和笔进行创作,不过在画家和作家面前只有同一个资源包含纸和笔,画家和作家拿着彼此都需要的资源不肯放手,并且互相都想拿到对方的资源这就是线程死锁

二、代码实现

##1.资源类

public class Resource {
	private Pen pen;
	private Paper paper;
	
    
	public Resource() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Resource(Pen pen, Paper paper) {
		super();
		this.pen = pen;
		this.paper = paper;
	}

	public Pen getPen() {
		return pen;
	}

	public void setPen(Pen pen) {
		this.pen = pen;
	}

	public Paper getPaper() {
		return paper;
	}

	public void setPaper(Paper paper) {
		this.paper = paper;
	}
    
}

2.创建画家和作家

###1.画家类

public class Painter extends Thread{
	private Resource resource;
	//将测试类创造好的resource对象传递进来,保证作家和画家公用一个resource资源
	public void prepare(Resource resource) {
		this.resource = resource;
	}
    @Override
    public void run() {
    	// TODO Auto-generated method stub
    	super.run();
    	Paper paper = resource.getPaper();//获取resource中的纸
    	//画家子线程在在拿到纸的同时去获取笔
    	synchronized (paper) {
    		//锁住resource中的纸,达到画家同时拿到之和笔的要求
			System.out.println("画家拿到了纸");
			try {
				Thread.sleep(1000*2);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Pen pen = resource.getPen();
	    	synchronized (pen) {
			   System.out.println("画家拿到了笔在创作");	
			}
		}
    		
		}
    }


###2.作家类

public class Writer extends Thread {
	private Resource resource;

	//将测试类创造好的resource对象传递进来,保证作家和画家公用一个resource资源
	public void prepare(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		Pen pen = resource.getPen();
		synchronized (pen) {
			System.out.println("作家拿到了笔");
			try {
				Thread.sleep(1000*9);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Paper paper = resource.getPaper();
			synchronized (paper) {
				System.out.println("作家拿到了纸在写作");
		}
		
		}
	}
}

##3.测试类

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建纸和笔的对象
       Pen pen = new Pen();
       Paper paper = new Paper();
       
       //创建resource
       Resource resource = new Resource(pen, paper);
       //创建作家对象
       Writer writer = new Writer();
       writer.prepare(resource);//传递resource保证作家和画家公用一个resource资源
     //创建画家对象
       Painter painter = new Painter();
       painter.prepare(resource);
       //开启画家和作家的子线程
       writer.start();
       painter.start();
	}

}

总结

1.线程死锁指的的是画家和作家都需要拿到纸和笔,画家先拿到纸作家先拿到笔,彼此抱着不放,并且想要拿到对方手里的资源
2.解决线程死锁–设置画家在线程开启之后先进行休眠,确保作家线程执行完成,这样就不会导致多个线程操作同一个资源,造成线程死锁

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值