常用的模型有基于synchronized,lock,BlockingQueue3种,但是第一种已经基本很少用了,这里就不写了!
1:基于Lock的生产者与消费者模型
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerAndConsumerLockTest {
private final int MAX_LEN = 10; // 指定队列最长长度
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private Queue<Integer> queue = new LinkedList<Integer>();
class Producer extends Thread{
@Override
public void run() {
producer();
}
private void producer(){
while (true){
lock.lock();
try {
while (queue.size() == MAX_LEN){
System.out.println("当前生产消费阻塞队列已满");
try {
condition.await(); // 造成当前线程在接到信号或被中断之前一直处于等待状态(下面的程序将不再执行,等待被唤醒)
}catch (Exception e){
e.printStackTrace();
}
}
queue.add(1); // 队列添加数据
condition.signal(); // 唤醒一个等待线程
System.out.println("生产者生产一条任务,当前队列长度为:" + queue.size());
try {
Thread.sleep(new Random().nextInt(399) + 100);
}catch (Exception e){
e.printStackTrace();
}
}finally {
lock.unlock();
}
}
}
}
class Consumer extends Thread{
@Override
public void run() {
consumer();
}
private void consumer(){
while(true){
lock.lock();
try{
while(queue.size() == 0){
System.out.println("当前生产消费阻塞队列为空");
try {
condition.await(); // 造成当前线程在接到信号或被中断之前一直处于等待状态(下面的程序将不再执行,等待被唤醒)
}catch (Exception e){
e.printStackTrace();
}
}
queue.poll(); // 队列消费数据
condition.signal(); // 唤醒一个等待线程
System.out.println("消费者消费一条任务,当前队列长度为" + queue.size());
try {
Thread.sleep(new Random().nextInt(399) + 100);
}catch (Exception e){
e.printStackTrace();
}
}finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) {
ProducerAndConsumerLockTest producerAndConsumerLockTest = new ProducerAndConsumerLockTest();
Producer producer = producerAndConsumerLockTest.new Producer();
Consumer consumer = producerAndConsumerLockTest.new Consumer();
producer.start();
consumer.start();
}
}
2:基于BlockingQueue的生产者与消费者模型
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ProducerAndConsumerBlockingQueueTest {
private BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(10); // 指定队列最长长度
class Producer extends Thread{
@Override
public void run() {
producer();
}
private void producer(){
while(true){
try {
queue.put(1); // 若向队尾添加元素的时候发现队列已经满了会发生阻塞一直等待空间,以加入元素(add:若超出了度列的长度会直接抛出异常。)
}catch (Exception e){
e.printStackTrace();
}
System.out.println("生产者生产一条任务,当前队列长度为" + queue.size());
try {
Thread.sleep(new Random().nextInt(399) + 100);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
class Consumer extends Thread{
@Override
public void run() {
consumer();
}
private void consumer(){
while (true){
try {
queue.take(); // 若队列为空,发生阻塞,等待有元素(poll: 若队列为空,返回null。)
}catch (Exception e){
e.printStackTrace();
}
System.out.println("消费者消费一条任务,当前队列长度为" + queue.size());
try {
Thread.sleep(new Random().nextInt(399) + 100);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
ProducerAndConsumerBlockingQueueTest producerAndConsumerBlockingQueueTest = new ProducerAndConsumerBlockingQueueTest();
Producer producer = producerAndConsumerBlockingQueueTest.new Producer();
Consumer consumer = producerAndConsumerBlockingQueueTest.new Consumer();
producer.start();
consumer.start();
}
}