- 阻塞队列(BlockingQueue)是队列的子接口,但他主要的作用不是作为容器,而是作为线程同步的容器:当生产者试图向阻塞队列中放入元素时,如果队列已经满了,那么这个生产者线程将被阻塞;如果一个消费者试图从阻塞队列中取出元素时,如果队列已经空了,那么这个消费者线程将被阻塞。
- 阻塞队列有三个方法可以向队列中添加元素:
- put:如果队列满了,将会发生阻塞
- offer:如果队列满了,将会返回flase
- add:如果队列满了,将会抛出异常
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class BlockingQueueTest { public static void main(String args[]) throws Exception{ BlockingQueue blockingQueue = new ArrayBlockingQueue<>(2); blockingQueue.put("java"); blockingQueue.put("java"); // blockingQueue.put("java"); // blockingQueue.add("java"); System.out.println(blockingQueue.offer("java") + ""); } }
-
以下定义一个容量为1的阻塞队列,三个生产者线程都只有在消费者线程将队列内容消费之后才可以继续向队列中添加元素
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class Producer extends Thread { private BlockingQueue<String> bq; public Producer(BlockingQueue<String> bq){ this.bq = bq; } public void run(){ String [] strArr = new String[]{ "java", "Struts", "Spring" }; for(int i=0 ; i<999999999; i++){ System.out.println(getName() + "生产者准备生产元素!"); try { Thread.sleep(200); bq.put(strArr[i % 3]); }catch (Exception e){ e.printStackTrace(); } System.out.println(getName() + "生产完成: " + bq); } } } class Consumer extends Thread{ private BlockingQueue<String> bq; public Consumer(BlockingQueue<String> bq){ this.bq = bq; } public void run(){ while (true){ System.out.println(getName() + "消费者准备消费集合元素! "); try{ Thread.sleep(200); bq.take(); }catch (Exception e){ e.printStackTrace(); } System.out.println(getName() + "消费完成: " + bq); } } } class BlockingQueueTest2{ public static void main(String args[]){ BlockingQueue<String> bq = new ArrayBlockingQueue<>(1); new Producer(bq).start(); new Producer(bq).start(); new Producer(bq).start(); new Consumer(bq).start(); } }
这是我看李刚编著的《疯狂Java讲义》后总结出来的。