渚漪Day01——JavaSE学习笔记【死锁】&【消费者生产者问题】

死锁情况

java代码

public class Suo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		through p1 = new through(0,"小渚");
		through p2 = new through(1,"小漪");
		p1.start();
		p2.start();
	}

}
class Left{
	
}
class Right{
	
}

class through extends Thread{
	static Left left = new Left();
	static Right right = new Right();
	String Name;
	int choice;
	public through(int choice,String Name) {
		this.choice=choice;
		this.Name=Name;
	}
	
	@Override
	public void run() {
		try {
			cross();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void cross() throws InterruptedException{
		
		if(choice==0){
			synchronized (left) {//获得桥左边的锁
				System.out.println(Name+"走上独木桥左边");
				Thread.sleep(1000);
				synchronized (right) {//获得桥右边的锁
					System.out.println(Name+"走上独木桥右边");
				}
			}
		}
		else{
			synchronized (right) {//获得桥右边的锁
				System.out.println(Name+"走上独木桥右边");
				Thread.sleep(2000);
				synchronized (left) {//获得桥左边的锁
					System.out.println(Name+"走上独木桥左边");
				}
			}
		}
	}
}

在这里插入图片描述
此处仍处于运行状态,双方分别站在独木桥的两边,导致死锁。

生产者消费者问题

代码显示

public class pro_cus {
	public static void main(String[] args) {
		Container container = new Container();
		new Producter(container).start();
		new Customer(container).start();
	}
}


class Producter extends Thread{
	Container container;
	public Producter( Container container) {
		this.container=container;
	}
	@Override
	public void run() {
		for(int i=1;i<=20;++i)//放入20个号码的产品
		{
			container.put(new Product(i));
			System.out.println("放入了"+i+"号产品");
		}
	}
}

class Customer extends Thread{
	Container container;
	public Customer( Container container) {
		this.container=container;
	}
	@Override
	public void run() {
		for(int i=0;i<20;++i)//消费20次
		{
			System.out.println("消费了"+container.get().name+"号产品");
		}
	}
}

class Product{
	int name;
	public Product(int i){
		name=i;
	}
}

class Container{//容器存放产品
	Product[] products = new Product[10];
	int count = 0;//计数器
	
	//生产者放产品
	public synchronized void put(Product product){
		if(count==products.length){//通知消费者消费,生产者等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notifyAll();
		if(count>10)System.out.println("error");
		products[count]=product;
		count++;
		
	}
	
	//消费者取产品
	public synchronized Product get() {
		if(count==0) {//通知生产者生产,消费者等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notifyAll();
		
		count--;
		Product product = products[count];
		return product;
	}
	
}

结果显示

结果完全随机,这个结果是我认为挺能反映题目要求的结果之一。在放入1-10号产品,缓冲区并没有达到上限,故生产者可以一直生产(当然同时消费者也能一直消费,这只是情况之一)。当达到上限,生产者不能生产,而消费者仍可以进行消费。直到消费者消费完,生产者没有生产结束。

在这里插入图片描述

放入了1号产品
放入了2号产品
放入了3号产品
放入了4号产品
放入了5号产品
放入了6号产品
放入了7号产品
放入了8号产品
放入了9号产品
放入了10号产品
消费了9号产品
消费了10号产品
消费了11号产品
消费了8号产品
消费了7号产品
消费了6号产品
消费了5号产品
放入了11号产品
消费了4号产品
放入了12号产品
消费了12号产品
放入了13号产品
消费了13号产品
放入了14号产品
消费了14号产品
放入了15号产品
消费了15号产品
放入了16号产品
消费了16号产品
放入了17号产品
消费了17号产品
放入了18号产品
消费了18号产品
放入了19号产品
消费了19号产品
放入了20号产品
消费了20号产品
消费了3号产品
消费了2号产品
消费了1号产品

问题1

虽然基本符合题目,但仍然存在,如图在这里插入图片描述

首先消费11号,再放入11号这样的逻辑错误

问题2

测试中,会出现放入数目count大于10的结果,但是程序并没有报错

并没有出现 java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10 这样数组越界的情况

在这里插入图片描述

原因

推测,程序生应该没有问题。应该是System.out.println()函数,打印时间与程序内部运行时间差较大导致。问题1是因为在执行打印“放入11号产品”前,“消费11号产品”这段话被提前打印出来。同理,问题2提前打印“放入15号产品”,但程序上已经执行完了消费14号产品导致。

改进方法

讲输出也放入get 和 put函数内部,即可解决。

当然此时IO效率会影响程序内部运行效率,每次计算都得等输出结束在进行。

最终代码

public class pro_cus {
	public static void main(String[] args) {
		Container container = new Container();
		new Producter(container).start();
		new Customer(container).start();
	}
}


class Producter extends Thread{
	Container container;
	public Producter( Container container) {
		this.container=container;
	}
	@Override
	public void run() {
		for(int i=1;i<=20;++i)//放入20个号码的产品
		{
			container.put(new Product(i));
		}
	}
}

class Customer extends Thread{
	Container container;
	public Customer( Container container) {
		this.container=container;
	}
	@Override
	public void run() {
		for(int i=0;i<20;++i)//消费20次
		{
			container.get();
		}
	}
}

class Product{
	int name;
	public Product(int i){
		name=i;
	}
}

class Container{//容器存放产品
	Product[] products = new Product[10];
	int count = 0;//计数器
	
	//生产者放产品
	public synchronized void put(Product product){
		while(count>=products.length){//通知消费者消费,生产者等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notifyAll();
		if(count>10)System.out.println("error");
		products[count]=product;
		count++;
		System.out.println("放入了"+product.name+"号产品");
	}
	
	//消费者取产品
	public synchronized void get() {
		if(count==0) {//通知生产者生产,消费者等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notifyAll();
		
		count--;
		Product product = products[count];
		System.out.println("消费了"+product.name+"号产品");
	}
	
}

最终结果

放入了1号产品
放入了2号产品
放入了3号产品
放入了4号产品
放入了5号产品
放入了6号产品
放入了7号产品
放入了8号产品
放入了9号产品
放入了10号产品
消费了10号产品
放入了11号产品
消费了11号产品
放入了12号产品
消费了12号产品
放入了13号产品
消费了13号产品
放入了14号产品
消费了14号产品
消费了9号产品
消费了8号产品
消费了7号产品
消费了6号产品
消费了5号产品
消费了4号产品
消费了3号产品
消费了2号产品
消费了1号产品
放入了15号产品
放入了16号产品
放入了17号产品
放入了18号产品
放入了19号产品
放入了20号产品
消费了20号产品
消费了19号产品
消费了18号产品
消费了17号产品
消费了16号产品
消费了15号产品


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值