Java多线程并发采用BlockingQueue阻塞队列实现生产者和消费者模式

1、BlockingQueue简介

BlockingQueue 通常用于一个线程生产对象,而另外一个线程消费这些对象的场景。
一个线程往里边放,另外一个线程从里边取的一个 BlockingQueue。
一个线程将会持续生产新对象并将其插入到队列之中,直到队列达到它所能容纳的临界点。也就是说,它是有限的。如果该阻塞队列到达了其临界点,负责生产的线程将会在往里边插入新对象时发生阻塞。它会一直处于阻塞之中,直到负责消费的线程从队列中拿走一个对象。
负责消费的线程将会一直从该阻塞队列中拿出对象。如果消费线程尝试去从一个空的队列中提取对象的话,这个消费线程将会处于阻塞之中,直到一个生产线程把一个对象丢进队列。

2、BlockingQueue的放入数据put()方法简介

put()方法将指定元素插入此队列中,将等待可用的空间.通俗点说就是某个值>maxSize 时候,就阻塞,直到能够有足够空间插入元素。

3、BlockingQueue的获取数据take()方法简介

take()方法获取并移除此队列的头部,说通俗点就是拿出来并且删掉,在元素变得可用之前一直等待 。queue的长度 == 0 的时候,一直阻塞,直到生产者又放入了新的数据。

4、生产者代码

package QueueTest;

import java.util.concurrent.BlockingQueue;
/**
 * 生产者类
 * @author 小轩
 *
 */
public class ProducterQueue implements Runnable {
	private final BlockingQueue proQueue;
	
	public ProducterQueue(BlockingQueue proQueue) {
		// TODO Auto-generated constructor stub
		this.proQueue = proQueue;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 10; i++) {
			try {
				//放入10瓶可乐 编号为0到9 也就是1-10 i初始单位为0
				//put()方法将指定元素插入此队列中,将等待可用的空间.通俗点说就是>maxSize 时候,阻塞,直到能够有空间插入元素
				System.out.println("生产的可乐编号为:"+i);
				proQueue.put(i);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}

5、消费者代码

package QueueTest;

import java.util.concurrent.BlockingQueue;
/**
 * 消费者类
 * @author 小轩
 *
 */
public class ConsumerQueue implements Runnable {
	
	private final BlockingQueue conQueue;
	
	public ConsumerQueue(BlockingQueue conQueue) {
		// TODO Auto-generated constructor stub
		this.conQueue = conQueue;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 10; i++) {
			try {
				//take()方法获取并移除此队列的头部,说通俗点就是拿出来并且删掉,在元素变得可用之前一直等待 。queue的长度 == 0 的时候,一直阻塞,直到生产者又放入了新的数据。
				System.out.println("**************消费者消费的可乐编号为:"+conQueue.take());
				//休眠一下方便看的更清楚
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

}

6、主程序入口类

package QueueTest;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * 主程序入口类
 * @author 小轩
 *
 */
public class test {
	public static void main(String[] args) {
		//自定义大小为5一个盒子 这里需要注意0到5是六次
		BlockingQueue publicQueue = new LinkedBlockingQueue(5);
		//实例化生产者
		ProducterQueue pro = new ProducterQueue(publicQueue);
		//实例化消费者
		ConsumerQueue con = new ConsumerQueue(publicQueue);
		//实例化生产者线程
		Thread t1 = new Thread(pro);
		//实例化消费者线程
		Thread t2 = new Thread(con);
		//启动两个线程
		t1.start();
		t2.start();
	}

}

7、遇到困难可以评论(有信必回)小轩微信17382121839。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章