阻塞队列LinkedBlockingQueue用法
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。
注:什么叫线程安全?这个首先要明确。线程安全就是说多线程访问同一代码,不会产生不确定的结果。
并行和并发区别
1、并行是指两者同时执行一件事,比如赛跑,两个人都在不停的往前跑;
2、并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率
LinkedBlockingQueue
由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
public class BlockingQueueTest2 { public class Basket { BlockingQueue<String> blockingQueue = new LinkedBlockingDeque<>(); public void produce () throws InterruptedException{ blockingQueue.put("An apple"); } public String consume() throws InterruptedException { // take方法取出一个苹果,若basket为空,等到basket有苹果为止(获取并移除此队列的头部) return blockingQueue.take(); } } public class Product implements Runnable { private String instance; private Basket basket; public Product(String instance, Basket basket) { this.instance = instance; this.basket = basket; } @Override public void run() { while (true){ try { ViseLog.e("生产者准备生产苹果:" + instance); basket.produce(); ViseLog.e("生产者消费生产苹果:" + instance); Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Consumer implements Runnable { private String instance; private Basket basket; public Consumer(String instance, Basket basket) { this.instance = instance; this.basket = basket; } public void run() { try { while (true) { // 消费苹果 ViseLog.e("消费者准备消费苹果:" + instance); ViseLog.e(basket.consume()); ViseLog.e("!消费者消费苹果完毕:" + instance); // 休眠1000ms Thread.sleep(1000); } } catch (InterruptedException ex) { System.out.println("Consumer Interrupted"); } } } }
BlockingQueueTest2 blockingQueueTest2 =new BlockingQueueTest2() ; BlockingQueueTest2.Basket basket = blockingQueueTest2 .new Basket(); ExecutorService service = Executors.newCachedThreadPool(); BlockingQueueTest2.Product producer =blockingQueueTest2 .new Product("生产者001", basket); // BlockingQueueTest2.Product producer1 =blockingQueueTest2 .new Product("生产者001", basket); BlockingQueueTest2. Consumer consumer = blockingQueueTest2 .new Consumer("消费者001", basket); service.submit(producer); // service.submit(producer1); service.submit(consumer);