进阶篇:同步阻塞队列之LinkedBlockingQueue(十一)

来源:互联网 发布:淘宝求购区在哪里 编辑:程序博客网 时间:2024/06/11 20:21

JDK为我们提供了多个阻塞队列的实现,什么是阻塞队列呢? 我们都知道队列就是一组数据的集合,而阻塞队列的意思是,当你往队列中取数据时,如果没有数据,你将被阻塞,一直等到拿到数据为止;

今天我们就来看一下比较常用的遵循先进先出的阻塞队列LinkedBlockingQueue;

//同步阻塞队列//可以看到,当调用take()方法去拿数据时,如果里面没有数据,将造成阻塞public static void blockingQueue(){final BlockingQueue<String> queue = new LinkedBlockingQueue<>();ExecutorService exec = Executors.newCachedThreadPool();//一个线程不断的往队列中取东西exec.execute(new Runnable() {public void run() {while( !Thread.currentThread().isInterrupted() ){try {String value = queue.take();System.out.println("线程"+Thread.currentThread()+"拿到数据:"+value);} catch (InterruptedException e) {e.printStackTrace();}}}});//一个线程不断的往队列中放东西exec.execute(new Runnable() {public void run() {while( !Thread.currentThread().isInterrupted() ){try {TimeUnit.MILLISECONDS.sleep(1000);int number = new Random().nextInt(1000);System.out.println("写入数据:"+number);queue.put(number+"");} catch (InterruptedException e) {e.printStackTrace();}}}});}


简单吧!一个线程写数据,一个线程读数据,当读数据的线程调用queue.take()往队列中拿数据时,如果队列中没有数据,它就一直阻塞,直到写数据的线程通过queue.put()方法写入数据为止! 是不是比我们自己写wait()和notify()要简单好用的多呢?!


对比上一篇文章的生产者消费者的实现,如果我们采用阻塞队列来实现的话,会变成什么样子呢?我们来看一下吧!

//餐厅class BlockingRestaurant{public BlockingQueue<String> queue = new LinkedBlockingQueue<>();}//食物消费者(顾客)class BlockingConsumer{//在这家餐厅就餐private BlockingRestaurant res = null;public BlockingConsumer( BlockingRestaurant res ) {this.res = res;}//吃食物方法public void eat() throws InterruptedException{while( !Thread.currentThread().isInterrupted() ){if( res.queue.take()!=null ){System.out.println("开始吃食物...");TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));//吃食物时间System.out.println("食物吃完了!...");}}}}//食物提供者(厨师)class BlockingProvider{//在这家餐厅工作private BlockingRestaurant res =  null;public BlockingProvider( BlockingRestaurant res ) {this.res = res;}public void fry() throws InterruptedException{//炒菜while( !Thread.currentThread().isInterrupted() ){System.out.println("开始做食物...");TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));res.queue.put("一份食物");System.out.println("食物做完了!...");}}}
//经典生产者与消费者演示(采用队列)public static void producerByQueue(){ExecutorService exec = Executors.newCachedThreadPool();BlockingRestaurant res = new BlockingRestaurant();final BlockingConsumer consumer = new BlockingConsumer(res);final BlockingProvider provider = new BlockingProvider(res);exec.execute(new Runnable() {public void run() {try {consumer.eat();} catch (InterruptedException e) {e.printStackTrace();}}});exec.execute(new Runnable() {public void run() {try {provider.fry();} catch (InterruptedException e) {e.printStackTrace();}}});}

简单多了吧!  Ok,这就是LinkedBlockingQueue的使用方法,后面我们会再介绍优先级队列,延时队列等等多种队列,它们将实现更有趣的功能!


1 0
原创粉丝点击