今天要講的BlockingQueue
可謂是大名鼎鼎,在併發編程中比較常見的一個類。編程
BlockingQueue
顧名思義是表示一個阻塞隊列,注意這兩個詞:阻塞和隊列。能夠拿咱們熟悉的生產者-消費者隊列來舉例,一條流水線上,A生產零件,B組裝零件,A就是生產者,B是消費者。若是A生成的太快,則零件堆積,A須要休息一下子等待B把零件消費完;若是A生產的太慢,則B變得無活可幹,被迫休息。併發
在BlockingQueue
中offer()
和put()
就是把零件放到隊列中,poll()
和take()
就是從隊列中取出零件進行消費。須要注意的是put()
和take()
是阻塞方法,而offer()
和poll()
是非阻塞方法,也就是put()
的時候隊列滿了,則阻塞;而offer()
的時候隊列滿了,則返回false,不阻塞。take()
和poll()
方法同理。.net
BlockingQueue
是一個接口,使用起來比較簡單。他的實現類以下:
比較經常使用的是ArrayBlockingQueue
和LinkedBlockingQueue
,從名字也能夠看出來,ArrayBlockingQueue
適合作有界隊列,LinkedBlockingQueue
適合作無界隊列。
這裏只看一下簡單使用:線程
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10); queue.put("abc"); queue.take();
通常來講put()
和take()
方法會分散在兩個或多個線程中。code
若是你的好奇心比較重,想研究一下BlockingQueue
的實現原理,那麼當你看一下ArrayBlockingQueue
的源碼,就會發現一些有趣的東西:blog
/** Main lock guarding all access */ final ReentrantLock lock; /** Condition for waiting takes */ private final Condition notEmpty; /** Condition for waiting puts */ private final Condition notFull;
啊哈,就是咱們前面講過的ReentrantLock
和Condition
了,請參考:https://my.oschina.net/lizaizhong/blog/1825244接口