生产者与消费者的理解
简单说就是一个类甚至多个类负责生产,同理消费者也是如此。
举例来说,一个变量,生产者不断增加;消费者不断减少。不论是在实际生活当中还是互联网应用当中都是如此,比如12306抢票、包子铺做包卖包、银行存取转账等。
代码如下:
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 WoTou{
int id;//给每个窝头作个记号
public WoTou(int id) {
this.id = id;
}
@Override
public String toString() {
return "WoTou :" + id ;
}
}
class SyncStack {//篮子类
int index = 0;
WoTou[] arrWT=new WoTou[6];//篮子容量为6
public synchronized void push(WoTou wt){//往里增加窝头的方法
while(index==arrWT.length){
/*篮子装满了就执行wait等待,如果这里使用if执行完try语句就会跳出if
* 然后执行notify语句叫醒,接着往装满的篮子继续装包子就会出现数组下标越界异常*/
try{
this.wait();//不是当前线程wait而是当前访问的这个线程wait
}catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();//一般wait方法与notify互相对应:wait负责等待,notify负责叫醒
arrWT[index]=wt;//将传进来的窝头赋值给arrWT数组下标
index++;//每次+1
//synchronized保证多个线程添加窝头的时候能数据一致
}
public synchronized WoTou pop(){//往外拿窝头的方法
while(index==0){//
try{
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index--;
return arrWT[index];
}
}
class Producer implements Runnable{//生产类
SyncStack ss=null;//设置初始值篮子为空
public Producer(SyncStack ss) {
this.ss = ss;
//然后把局部变量传递给成员变量,即将做好的窝头放在篮子里
}
@Override
public void run() {
for(int i=0;i<20;i++){
WoTou wt=new WoTou(i);
ss.push(wt);
//将生产的窝头使用push方法增加实现
System.out.println("生产了:"+ wt);
try {
Thread.sleep((int)(Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{//消费类
SyncStack ss=null;
public Consumer (SyncStack ss) {
this.ss = ss;
}
@Override
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();
}
}
}
}
运行结果如下:
生产了:WoTou :0
消费了:WoTou :0
生产了:WoTou :1
消费了:WoTou :1
生产了:WoTou :2
消费了:WoTou :2
生产了:WoTou :3
消费了:WoTou :3
生产了:WoTou :4
消费了:WoTou :4
生产了:WoTou :5
消费了:WoTou :5
生产了:WoTou :6
消费了:WoTou :6
生产了:WoTou :7
生产了:WoTou :8
消费了:WoTou :8
生产了:WoTou :9
生产了:WoTou :10
消费了:WoTou :10
生产了:WoTou :11
消费了:WoTou :11
生产了:WoTou :12
生产了:WoTou :13
消费了:WoTou :13
生产了:WoTou :14
消费了:WoTou :14
生产了:WoTou :15
消费了:WoTou :15
生产了:WoTou :16
消费了:WoTou :16
生产了:WoTou :17
消费了:WoTou :17
生产了:WoTou :18
消费了:WoTou :18
生产了:WoTou :19
消费了:WoTou :19
消费了:WoTou :12
消费了:WoTou :9
消费了:WoTou :7
2)
import java.util.LinkedList;
import java.util.Random;
public class Test {
public static void main(String[] args) {
Mystorage ss=new Mystorage();
Producer p=new Producer(ss);
Consumer c=new Consumer(ss);
new Thread(p).start();
new Thread(c).start();
}
}
class Mystorage{
LinkedList<Object> list=new LinkedList<>();
static final int MAX_CAPACITY=100;
public synchronized void store(String product){
while(list.size()>MAX_CAPACITY){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.offer(product);
System.out.println(Thread.currentThread().getName()+"\t存储了:"+product);
notify();
}
public synchronized void take(){
while(list.size()==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object product=list.poll();
System.out.println(Thread.currentThread().getName()+"\t消费了:"+product);
notify();
}
}
class Producer implements Runnable{
Mystorage storag=new Mystorage();
public Producer(Mystorage storag) {
super();
this.storag = storag;
}
@Override
public void run() {
for(int i=1;i<10;i++){
String product="产品编号:"+new Random().nextInt(10);
storag.store(product);
}
}
}
class Consumer implements Runnable{
Mystorage storag=new Mystorage();
public Consumer(Mystorage storag) {
super();
this.storag = storag;
}
@Override
public void run() {
for(int i=1;i<10;i++){
String product="产品编号:"+new Random().nextInt(10);
storag.take();
}
}
}
运行结果如下:
Thread-0 存储了:产品编号:1
Thread-1 消费了:产品编号:1
Thread-0 存储了:产品编号:0
Thread-0 存储了:产品编号:4
Thread-0 存储了:产品编号:0
Thread-0 存储了:产品编号:8
Thread-0 存储了:产品编号:7
Thread-0 存储了:产品编号:2
Thread-1 消费了:产品编号:0
Thread-0 存储了:产品编号:6
Thread-1 消费了:产品编号:4
Thread-0 存储了:产品编号:9
Thread-1 消费了:产品编号:0
Thread-1 消费了:产品编号:8
Thread-1 消费了:产品编号:7
Thread-1 消费了:产品编号:2
Thread-1 消费了:产品编号:6
Thread-1 消费了:产品编号:9