Java知识点——线程通信(线程之间的联系)

2020-03-17 18:01:28 浏览数 (1)

1. 生活化例子

预约 --> 抢购 消费者 <–> 商品 <–> 生产者

消费者 1. 购买商品 2. 等待,不过在等待之前,需要告知生产者快点生产

生产者: 1. 生产商品 2. 休息,在休息之前,要告知消费者你快来买啊

商品: 就是两个独立线程之间的共享资源。

2. 共享资源处理问题

现在存在两个完全无关的线程:生产者和消费者,但是商品会作为他们两者之间的共享资源。 生产者和消费者中都有一个成员变量 商品类型

【解决方案】 创建生产者或者消费者线程对象时,使用同一个商品类对象,作为构造方法参数进行初始化操作

3. 设计程序

代码如下: 消费者

代码语言:javascript复制
package thread;


public class Customor implements Runnable{
	private Goods goods = null;
	
	public Customor() {
		super();
	}
	public Customor(Goods goods) {
		super();
		this.goods = goods;
	}
	
	@Override
	public void run() {
		while (true) {
			synchronized (goods) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				if (!goods.isProduct()) {
					System.out.println("消费者购买"   goods.getName()   ":"   goods.getPrice());

					goods.setProduct(true);
					// 没货了
					System.out.println("唤醒生产者");
					// 唤醒生产者Producer线程
					goods.notify();
				} else {
					// 此时商品状态为true,也就是说,没商品,需要生产
					System.out.println("消费者进入无线等待状态");
					try {
						goods.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}

生产者:

代码语言:javascript复制
package thread;

public class Producer implements Runnable{
	
	private Goods goods = new Goods();
	
	public Producer() {
		super();
	}

	public Producer(Goods goods) {
		super();
		this.goods = goods;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (goods) {

				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (goods.isProduct()) {
					// 这里是一个数学方法,概率设定
					if (Math.random() > 0.5) {
						goods.setName("红烧茄子");
						goods.setPrice(25);
					} else {
						goods.setName("蛋炒饭");
						goods.setPrice(15);
					}

					// 修改标记
					goods.setProduct(false);
					System.out.println("生产了"   goods.getName()   "价格:"   goods.getPrice());

					// 唤醒消费者
					System.out.println("唤醒消费者");
					goods.notify();

				} else {
					System.out.println("生产者进入无限等待");
					try {
						goods.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}

商品:

代码语言:javascript复制
package thread;

public class Goods {	
	private String name;
	private float price;
	private boolean product;
	
	public Goods(){}

	public Goods(String name, float price, boolean product) {
		super();
		this.name = name;
		this.price = price;
		this.product = product;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	public boolean isProduct() {
		return product;
	}

	public void setProduct(boolean product) {
		this.product = product;
	}
}

主函数:

代码语言:javascript复制
package thread;

public class Demo1 {
	public static void main(String[] args) {
		Goods goods = new Goods("锅巴肉片",35,true);
		
		
		//这是按部就班  还可以使用匿名对象来调用start方法
		//day22SL  可见
		Producer producer = new Producer(goods);
		Customor customor = new Customor(goods);
		
		Thread thread1 = new Thread(producer);
		Thread thread2 = new Thread(customor);
		
		thread1.start();
		thread2.start();
	}
}

0 人点赞