BlockingQueue接口是Queue的子接口,它的主要用途并不是作为容器,而是作为线程同步的的工具,因此他具有一个很明显的特性,当生产者线程试图向BlockingQueue放入元素时,如果队列已满,则线程被阻塞,当消费者线程试图从中取出一个元素时,如果队列为空,则该线程会被阻塞,正是因为它所具有这个特性,所以在程序中多个线程交替向BlockingQueue中放入元素,取出元素,它可以很好的控制线程之间的通信。
package com.queue;
import java.util.concurrent.BlockingQueue;
/***
* 消费者
* **/
public class Consumer extends Thread {
/***
* 利用队列存储样品
* */
private BlockingQueue<String> bq;
public Consumer() {
// TODO Auto-generated constructor stub
}
public Consumer(BlockingQueue<String> bq) {
super();
this.bq = bq;
}
@Override
public void run() {
while(true){
System.out.println(getName()+"消费者准备消费集合元素");
try{
Thread.sleep(2000);
//尝试取出元素,如果队列为空,则被线程阻塞
bq.take();
}catch(Exception e){
e.printStackTrace();
}
System.out.println(getName()+"消费完成"+bq);
}
}
}
生成者
package com.queue;
import java.util.concurrent.BlockingQueue;
/**
* 生产者
* **/
public class Producer extends Thread{
/***
* 利用队列存储样品
* */
private BlockingQueue<String> bq;
public Producer() {
// TODO Auto-generated constructor stub
}
public Producer(BlockingQueue<String> bq) {
this.bq = bq;
}
@Override
public void run() {
String []str=new String[]{"solr","lucene","nutch"};
for(int i=0;i<99999999;i++){
System.out.println(getName()+"生产者准备生产集合元素了!");
try{
Thread.sleep(2000);
//尝试放入元素,如果对列已满,则线程被阻塞
bq.put(str[i%3]);
}catch(Exception e){
e.printStackTrace();
}
System.out.println(getName()+"生产完成:"+bq);
}
}
}