Java並發之BlockingQueue的使用
一.簡介
前段時間看到有些朋友在網上發了一道面試題,題目的大意就是:有兩個線程A,B, A線程每200ms就生成一個[0,100]之間的隨機數, B線程每2S中打印出A線程所產生的增量隨機數。其實該題目筆者認為考察的知識點就是本博文要給大家介紹的BlockingQueue這個接口,對於該題目筆者認為考察的只是面試者對這個類是否掌握,別無其他。
二.BlockingQueue的使用
BlockingQueue是一個阻塞隊列,用戶可以為該隊列設置一個初始容量(即該隊列中最多能夠放入多少個數據)。既然是隊列,那么肯定是由順序的,我們可以調用給定的API依次獲取往該隊列中值的設置順序。關於API筆者在解決上述的面試題后,會挑一些重要的並且很常用的給讀者作詳細的說明。
以下代碼實例就是筆者解決該面試題的代碼,如果讀者有更好的解決方式,歡迎給筆者留言,若有錯誤之處,請多多指教。
public class BlockingQueueTest { /** * 實例化一個隊列,隊列中的容量為10 */ private static BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>(10); public static void main(String[] args) { ScheduledExecutorService product = Executors.newScheduledThreadPool(1); Random random = new Random(); product.scheduleAtFixedRate(() -> { int value = random.nextInt(101); try{ blockingQueue.offer(value); //offer()方法就是網隊列的尾部設置值 }catch(Exception ex){ ex.printStackTrace(); } }, 0, 200, TimeUnit.MILLISECONDS); //每100毫秒執行線程 new Thread(() -> { while(true){ try { Thread.sleep(2000); System.out.println("開始取值"); List<Integer> list = new LinkedList<>(); blockingQueue.drainTo(list); //drainTo()將隊列中的值全部從隊列中移除,並賦值給對應集合 list.forEach(System.out::println); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
三.BlockingQueue中API介紹
offer(E e): 將給定的元素設置到隊列中,如果設置成功返回true, 否則返回false. e的值不能為空,否則拋出空指針異常。
offer(E e, long timeout, TimeUnit unit): 將給定元素在給定的時間內設置到隊列中,如果設置成功返回true, 否則返回false.
add(E e): 將給定元素設置到隊列中,如果設置成功返回true, 否則拋出異常。如果是往限定了長度的隊列中設置值,推薦使用offer()方法。
put(E e): 將元素設置到隊列中,如果隊列中沒有多余的空間,該方法會一直阻塞,直到隊列中有多余的空間。
take(): 從隊列中獲取值,如果隊列中沒有值,線程會一直阻塞,直到隊列中有值,並且該方法取得了該值。
poll(long timeout, TimeUnit unit): 在給定的時間里,從隊列中獲取值,如果沒有取到會拋出異常。
remainingCapacity():獲取隊列中剩余的空間。
remove(Object o): 從隊列中移除指定的值。
contains(Object o): 判斷隊列中是否擁有該值。
drainTo(Collection c): 將隊列中值,全部移除,並發設置到給定的集合中。