package product_consumer.produce;
import java.util.concurrent.BlockingQueue;
/**
* @Package Name : ${PACKAG_NAME}
* @Author : 1766318593@qq.com
* @Creation Date : 2018年12月09日下午2:11
* @Function : todo
*
*
* add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
* remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
* element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
* offer 添加一个元素并返回true 如果队列已满,则返回false
* poll 移除并返问队列头部的元素 如果队列为空,则返回null
* peek 返回队列头部的元素 如果队列为空,则返回null
* put 添加一个元素 如果队列满,则阻塞
* take 移除并返回队列头部的元素 如果队列为空,则阻塞
*
*/
public class Producer implements Runnable{
BlockingQueue<String> queue;
public Producer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
int i = 0;
while (true) {
try {
System.out.println("生产者生产食物, 食物编号为:" + i);
queue.put(" 食物 " + i++);
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("生产者被中断");
}
}
}
}
package product_consumer.consumer;
import java.util.concurrent.BlockingQueue;
/**
* @Package Name : ${PACKAG_NAME}
* @Author : 1766318593@qq.com
* @Creation Date : 2018年12月09日下午2:12
* @Function : todo
*
* 用ArrayBlockingQueue解决生产者消费者问题;默认使用的是非公平锁
*
* take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止,若请求不到此线程被加入阻塞队列;
*
* 如果使用公平锁,当有内容可以消费时,会从队首取出消费者线程进行消费(即等待时间最长的线程)
*
* add(anObject):把anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则招聘异常
*/
public class Concumer implements Runnable{
BlockingQueue<String> queue;
public Concumer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
try {
System.out.println(Thread.currentThread().getName() + "消费:"
+ queue.take());
} catch (InterruptedException e) {
System.out.println("消费者被中断");
}
}
}
}
package product_consumer;
import product_consumer.consumer.Concumer;
import product_consumer.produce.Producer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @Package Name : ${PACKAG_NAME}
* @Author : 1766318593@qq.com
* @Creation Date : 2018年12月09日下午2:12
* @Function : todo
*/
public class testPC {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(20);
Thread pro = new Thread(new Producer(queue), "生产者");
pro.start();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new Concumer(queue), "消费者 " + i);
t.start();
}
}
}
reentrantlock 实现简单的生产者和消费者
package lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Package Name : ${PACKAG_NAME}
* @Author :
* @Creation Date : 2019年01月23日下午11:54
* @Function : todo
*/
public class MyArrayBlockingQueue<T> {
//维护的数据
private final T[] datas;
//数据的个数
private int count;
//插入取出的索引
private int put_index;
private int take_index;
//锁
private final Lock lock = new ReentrantLock();
//定义两个条件,分别为“集合满”和“集合空”
private Condition full = lock.newCondition();
private Condition empty = lock.newCondition();
//提供MyArrayBlockingQueue的构造方法,初始化T[]数据
public MyArrayBlockingQueue() {
this(10);
}
public MyArrayBlockingQueue(int maxSize) {
this.datas = (T[]) new Object[maxSize];
}
public void put(T data) {
// 不管put 还是 take的时候 都要先枷锁
lock.lock();
try {
if (count == datas.length) {
//此时集合已经满了
System.out.println("集合已满,请等待...");
//使调用线程挂起
full.await();
}
//不满则添加新元素
datas[put_index++] = data;
count++;
//此时唤醒等待取数据的线程
empty.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public T take() {
lock.lock();
try {
if (count == 0) {
//此时集合已经空了
System.out.println("集合已空,请等待...");
//使调用线程挂起
empty.await();
}
//不空则取出最后一个数据
take_index = count - 1;
T result = datas[take_index--];
count--;
//此时唤醒等待写数据的线程
full.signalAll();
return result;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
public static void main(String[] args ){
System.out.println("hellow ");
}
}