1 自己实现
public class ProducerConsumer {
public static void main(String[] args) {
SyncStack ss=new SyncStack();
Producer p=new Producer(ss);
Consumer c=new Consumer(ss);
new Thread(p).start();
new Thread(c).start();
}
}
class Producer implements Runnable{
public SyncStack ss=null;
public Producer(SyncStack ss){
this.ss=ss;
}
public void run(){
for(int i=0;i<20;i++){
WoTou wt=new WoTou(i);
ss.push(wt);
System.out.println("生产了:"+wt);
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
public SyncStack ss=null;
public Consumer(SyncStack ss){
this.ss=ss;
}
public void run(){
for(int i=0;i<20;i++){
WoTou wt=ss.pop();
System.out.println("消费了:"+wt);
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class SyncStack{
int index=0;
WoTou[] arrWT=new WoTou[6];//对象数组
public synchronized void push(WoTou wt){
while(index==arrWT.length){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index]=wt;
index++;
}
public synchronized WoTou pop(){
while(index==0){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[index];
}
}
class WoTou{
int id;
WoTou(int id){
this.id=id;
}
public String toString(){
return "WoTou: "+id;
}
}
输出:
生产了:WoTou: 0
消费了:WoTou: 0
生产了:WoTou: 1
消费了:WoTou: 1
生产了:WoTou: 2
消费了:WoTou: 2
生产了:WoTou: 3
消费了:WoTou: 3
生产了:WoTou: 4
2 使用BlockingQueue
</pre><pre name="code" class="java">import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class Bread{
public int id;
public Bread(){
}
public Bread(int id){
this.id=id;
}
public String toString(){
return "Bread: "+id;
}
}
class Producer implements Runnable{
//容器
private final ArrayBlockingQueue<Bread> queue;
public Producer(ArrayBlockingQueue<Bread> queue){
this.queue = queue;
}
@Override
public void run() {
while(true){
produce();
}
}
public void produce(){
/**
* put()方法是如果容器满了的话就会把当前线程挂起
* offer()方法是容器如果满的话就会返回false,也正是我在前一篇中实现的那种策略。
*/
try {
for(int i=0;i<10;i++){
Bread bread = new Bread(i);
queue.put(bread);
System.out.println("生产了:"+bread);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable{
//容器
private final ArrayBlockingQueue<Bread> queue;
public Consumer(ArrayBlockingQueue<Bread> queue){
this.queue = queue;
}
@Override
public void run() {
while(true){
consume();
}
}
public void consume(){
/**
* take()方法和put()方法是对应的,从中拿一个数据,如果拿不到线程挂起
* poll()方法和offer()方法是对应的,从中拿一个数据,如果没有直接返回null
*/
try {
for(int i=0;i<10;i++){
Bread bread = queue.take();
System.out.println("消费了:"+bread);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestBlockingQueue {
public static void main(String[] args) {
int capacity = 10;
ArrayBlockingQueue<Bread> queue = new ArrayBlockingQueue<Bread>(capacity);
new Thread(new Producer(queue)).start();
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
输出:
消费了:Bread: 1
消费了:Bread: 2
消费了:Bread: 3
消费了:Bread: 4
消费了:Bread: 0
消费了:Bread: 5
消费了:Bread: 3
消费了:Bread: 2
生产了:Bread: 5
生产了:Bread: 0
生产了:Bread: 1
生产了:Bread: 2
生产了:Bread: 3
生产了:Bread: 4
生产了:Bread: 5