生产者和消费者问题

第一种:使用wait()和notify()方法解决生产者和消费者问题:

关键步骤:

①要对入队和出队方法都加上“锁”,保证任意时刻只有一个线程访问资源;

②并且当队列已满或已空时,要调用wait()方法,让当前线程等待,直到被唤醒notify();

③在生产者和消费者线程中,可以在每一次入队和出队操作之后调用sleep()方法,让当前线程暂停释放CPU时间让另一线程执行,以实现入队出队依次交叉进行。

class synqueue {   //这是我们自己写的一个阻塞队列
	private int front = 0, rear = 0;
	final static int maxSize = 6;
	private char[] b = new char[maxSize];  //用数组模拟生产者与消费者共享资源区
	synchronized void enqueue(char c) {     //入队操作
		if ((rear + 1)%maxSize==front) {   //队列已满
			try {
				this.wait();           //暂停执行入队的线程,进入队列的wait池。
			} catch (InterruptedException e) {
			}
		}
		this.notify();                 //唤醒在此对象监视器上等待的单个线程
		rear = (rear + 1) % maxSize;    //得到队尾的位置
		b[rear] = c;                  //向队尾插入字符
	}
	synchronized char outquqeue() {      //出队操作
		if (front == rear) {             //队列已空
			try {
				this.wait();
			} catch (InterruptedException e) {
			}
		}
		this.notify();
		front = (front + 1) % maxSize;  //队首向下移一个
		return b[front];              //返回原队首的元素
	}
}
class producer implements Runnable {   //生产者线程
	synqueue sq;
	producer(synqueue sq1) {
		sq = sq1;
	}
	public void run() {
		char c;
		for (int i = 0; i < 10; i++) {
			c = (char) (Math.random() * 26 + 'A');
			sq.enqueue(c);
			System.out.println("producer=" + c);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}
	}
}
class customer implements Runnable {   //消费者线程
	synqueue sq;
	customer(synqueue sq1) {
		sq = sq1;
	}
	public void run() {
		char c;
		for (int i = 0; i < 10; i++) {
			c = sq.outquqeue();
			System.out.println("customer=" + c);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}
	}
}
public class ProducerConsumerPattern {	
	public static void main(String[] args) {
		synqueue sq = new synqueue();
		producer pro = new producer(sq);
		customer cus = new customer(sq);
		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(cus);
		t1.start();
		t2.start();
	}
}

第二种:使用阻塞队列解决生产者与消费者问题:

主要是使用java提供的BlockingQueue类的put()和take()方法。

public class ProducerConsumerPattern {
	public static void main(String args[]) {
		// 创建共享的阻塞队列
		BlockingQueue sharedQueue = new LinkedBlockingQueue();
		//创建生产者与消费者线程
		Thread prodThread = new Thread(new Producer(sharedQueue));
		Thread consThread = new Thread(new Consumer(sharedQueue));
		// 启动生产者与消费者线程
		prodThread.start();
		consThread.start();
	}
}
// 生产者线程
class Producer implements Runnable {
	private final BlockingQueue sharedQueue;
	public Producer(BlockingQueue sharedQueue) {
		this.sharedQueue = sharedQueue;
	}
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				System.out.println("Produced: " + i);
				sharedQueue.put(i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}
// 消费者线程
class Consumer implements Runnable {
	private final BlockingQueue sharedQueue;
	public Consumer(BlockingQueue sharedQueue) {
		this.sharedQueue = sharedQueue;
	}
	public void run() {
		while (true) {
			try {
				System.out.println("Consumed: " + sharedQueue.take());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值