Java并发之生产者消费者

这个例子有点局限,消费者每次只能等生产者生产了n个Q后消费完这n个。

 

 

package com.test;

class Q { 
	int n; 
	boolean valueSet = false; //Q的value是不是已经设置过了
	synchronized int get() { 
		if(!valueSet) 
			try { 
				wait(); //wait until Producer produce a product and notify ,释放锁
			} catch(InterruptedException e) { 
				System.out.println("InterruptedException caught"); 
			} 
		System.out.println("Got: " + n); 
		valueSet = false; 
		notify(); 
		return n; 
	} 
	
	synchronized void put(int n) { 
		if(valueSet) 
			try { 
				wait(); 
			} catch(InterruptedException e) { 
				System.out.println("InterruptedException caught"); 
			} 
		this.n = n; 
		valueSet = true; 
		System.out.println("Put: " + n); 
		notify(); 
	} 
}

class Producer implements Runnable { 
	Q q;
	
	Producer(Q q) { 
		this.q = q; 
		new Thread(this, "Producer").start(); 
	}
	
	public void run() { 
		int i = 0; 
		while(true) { 
			q.put(i++); 
		} 
	} 
}

class Consumer implements Runnable { 
	Q q;
	
	Consumer(Q q) { 
		this.q = q; 
		new Thread(this, "Consumer").start(); 
	} 
	
	public void run() { 
		while(true) { 
			q.get(); 
		}	 
	} 
}

class PCFixed { 
	public static void main(String args[]) { 
		Q q = new Q(); 
		new Consumer(q); 
		new Producer(q); 

		System.out.println("Press Control-C to stop."); 
	} 
}

 

 

下面的方法转自《程序员面试攻略》第二版,机械工业出版社,P118-P119,应该是正确的解答:

 

生产者:

 

 

public class Producer extends Thread {
      private IntBuffer buffer;
      
      public Producer(IntBuffer buffer) {
            this.buffer = buffer;
      }
 
      public void run() {
            Random r = new Random();
            while(true) {
                    int num = r.nextInt();
                    buffer.add(num);
                    System.out.println("Produced " + num);
            }
      }
}

 

消费者:

 

public class Consumer extends Thread {
	private IntBuffer buffer;
	
	public Consumer(IntBuffer buffer) {
		this.buffer = buffer;
	}
	
	public void run() {
		while(true) {
			int num = buffer.remove();
			System.out.println("Consumed " + num);
		}
	}
}

 

缓冲区:

 

public class IntBuffer {
	private int index;
	private int[] buffer = new int[8];
	
	public synchronized void add( int num ) {
		while(index == buffer.length-1) {
			try {
				wait();
			}catch(InterruptedException e) {

			}
		}

		buffer[index++] = num;
		notifyAll();
	}

	public synchronized int remove() {
		while(index == 0) {
			try {
				wait();
			}catch(InterruptedException e) {

			}			
		}
		
		int ret = buffer[--index];
		notifyAll();
		return ret;
	}
}
这段代码允许多个生产者和多个消费者使用同一个缓冲区,解决了第一个方法的缺陷。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值