Java基础之多线程实战(生产者与消费者模型)

使用到的方法和关键字

synchronized关键字:可以使线程一个个的执行
wait方法:使线程休眠,直到被唤醒才能执行
notifyAll方法:唤醒休眠的所有线程
Thread.sleep()方法:设置延迟时间,延迟一段时间再执行下面的代码

其他一些更为普遍的不再赘述。

问题描述

现在要求设置两个线程,一个生产者线程,一个消费者线程,当产品存货量等于0时不再进行消费等待唤醒,当产品存货量大于5时,不再进行生产等待唤醒,这个问题与其他问题的不同点在于,他的两个线程操作是不一样的。

出现的问题

首先也是最重要的是理解问题,要明白生产线程和消费线程是对同一个对象进行操作,不然没有任何意义,这样我们就需要再创建一个类存储公用的信息。

其次还有两个严重的问题。
第一,同步问题,如果不同步可能出现数据相同的状况。
第二,重复问题,不断重复生产线程数值会超过5,反之亦然,违背题目要求。

解决问题——思路

对于同步问题,我们采用synchronized同步代码块或者synchronized同步方法解决。对于重复问题,这里我们要借助存储公用信息的类,对它里面的不同方法进行休眠,用到了两个Object类中的wait和notify方法。

代码实现

//存储公用信息
class Message{
	private String proname;
	private int number;
	public Message(String proname,int number) {
		this.proname = proname;
		this.number = number;
	}
	public synchronized void product() {
		if(this.number>5) {
			try {
				super.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("生产"+this.proname+",存量:"+this.number++);
		super.notifyAll();
	}
	public synchronized void consume() {
		if(this.number==0) {
			try {
				super.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("消耗"+this.proname+",存量:"+this.number--);
		super.notifyAll();
	}
}
//实现生产者线程
class Producer implements Runnable{
	private Message mge;
	public Producer(Message mge) {
		this.mge = mge;
	}
	public void run() {
		for(int i=0;i<9;i++) {
			this.mge.product();
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
//实现消费者线程
class Consumer implements Runnable{
	private Message mge;
	public Consumer(Message mge) {
		this.mge = mge;
	}
	public void run() {
		for(int i=0;i<9;i++)
		{		
			this.mge.consume();
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
public class Demo6 {
	public static void main(String[] args) {
		Message mge = new Message("甜品",8);
		new Thread(new Producer(mge)).start();
		new Thread(new Consumer(mge)).start();
	}
}

你可能感兴趣的:(Java)