一,生产者
生产一样东西的人就是消费者,java里面生产数据的线程就是生产者线程
package jucdemo;
import java.util.Random;
/**
* @author 邓亚非
* 生产者线程
*/
public class Producer extends Thread {
private SuperMarket superMarket;
private String name;
public Producer(SuperMarket superMarket){
this.superMarket=superMarket;
}
@Override
public void run() {
while (true){
superMarket.producer();
try {
Thread.sleep(new Random().nextInt(500));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
二,消费者
消费生产者生产的对象就是消费者,java里面消费生产者线程产生的数据的线程叫做消费者线程
package jucdemo;
import java.util.Random;
/**
* @author 邓亚非
* 消费者线程
*/
public class Consumer extends Thread{
private SuperMarket superMarket;
private String name;
public Consumer(SuperMarket superMarket){
this.superMarket=superMarket;
}
@Override
public void run() {
while (true){
superMarket.consume();
try {
Thread.sleep(new Random().nextInt(500));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
三,仓库(数据存放地)
生产者生产的大小最终要到商场中去,消费者最终要到商场去消费,这个商场就是一个仓库,和日常生活是一样的
package jucdemo;
import java.util.ArrayList;
/**
* @author 邓亚非
* 商店
*/
public class SuperMarket {
private ArrayList<String> arrayList;
public SuperMarket(ArrayList arrayList){
this.arrayList=arrayList;
}
/**
* 生产方法
*/
public void producer(){
System.out.println("生产者生产前的食品数量:"+arrayList.size());
arrayList.add("哈哈哈");
System.out.println("生产者生产后的食品数量:"+arrayList.size());
}
/**
* 消费方法
*/
public void consume(){
System.out.println("消费者消费前的食品数量:"+arrayList.size());
if (arrayList.size()>0){
arrayList.remove(0);
System.out.println("消费后的食品数量:"+arrayList.size());
}
}
}
四,生产者消费者模型
1:解耦
生产者和消费者之间是独立存在的,互不影响的,仓库只是用来连接他们的,可以大大降低他们之间的依赖性,举个例子吧:假如你要写信给你朋友,这个时候邮递员是送信的,需要亲自到你这里取信,送信到你朋友那,如果这个时候她不敢了或者有事去了你和你朋友之间是不是不能通信了啊,所以说你非常的依赖这个邮递员,没有她就不能寄信,但是这个时候用用一个邮箱呢,你只要把这个心放到邮箱里面,送信的人看到了邮箱里有信,她就去送就行了,你的朋友只要到邮箱里取就行了,你们根本不要和邮递员打交道,也就是说不用再依赖她,这就是降低了依赖,这就是解耦
2:支持并发
生产者和消费者是可以并发进行的,他们是互不干扰的
从寄信的例子来看。如果没有邮筒,你得拿着信傻站在路口等邮递员过来收(相当于生产者阻塞);又或者邮递员得挨家挨户问,谁要寄信(相当于消费者轮询)。不管是哪种方法,效率都比较低。
注意:生产前不消费,消费没有结束没有进行下一次消费
以上是我们自己定义的一个仓库类supermarket,在java当中有一个并发类叫做ArrayBlockQuene,线程安全,我们只要用这个并发类就不要自己写了,来看一下:这是改进之后的代码
package jucdemo;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
/**
* @author 邓亚非
* 生产者线程
*/
public class Producer extends Thread {
// 并发类
private ArrayBlockingQueue<Integer> arrayBlockingQueue;
public Producer(ArrayBlockingQueue arrayBlockingQueue){
this.arrayBlockingQueue=arrayBlockingQueue;
}
@Override
public void run() {
while (true){
try {
System.out.println("生产者生产前的商品数量:"+arrayBlockingQueue.size());
arrayBlockingQueue.put(1);
System.out.println("生产者生产后的商品数量:"+arrayBlockingQueue.size());
Thread.sleep(new Random().nextInt(500));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package jucdemo;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
/**
* @author 邓亚非
* 消费者线程
*/
public class Consumer extends Thread{
// 并发类
private ArrayBlockingQueue<Integer> arrayBlockingQueue;
public Consumer(ArrayBlockingQueue arrayBlockingQueue){
this.arrayBlockingQueue=arrayBlockingQueue;
}
@Override
public void run() {
while (true){
try {
System.out.println("消费者消费前的商品数量:"+arrayBlockingQueue.size());
arrayBlockingQueue.take();
System.out.println("消费者消费后的商品数量:"+arrayBlockingQueue.size());
Thread.sleep(new Random().nextInt(500));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}