1 public void put(E e) throws InterruptedException { 2 if (e == null) throw new NullPointerException(); 3 final int c; 4 final Node<E> node = new Node<E>(e); 5 final ReentrantLock putLock = this.putLock; 6 final AtomicInteger count = this.count; 7 putLock.lockInterruptibly(); 8 try { 9 while (count.get() == capacity) { 10 notFull.await(); 11 } 12 enqueue(node); 13 c = count.getAndIncrement(); 14 if (c + 1 < capacity) 15 notFull.signal(); 16 } finally { 17 putLock.unlock(); 18 } 19 if (c == 0) 20 signalNotEmpty(); 21 }
如上是LinkedBlockingQueue的put方法的源代碼,從put方法中所采取的線程安全措施,可見一斑。
1、使用鎖機制。使用了ReentrantLock,可重入鎖,在做關鍵操作之前,先調用ReentrantLock的lockInterruptibly方法進行上鎖,在執行完成之后,調用unlock方法解鎖。
2、因為Blocking機制,隊列滿了,就要等有空余空間才能put新元素。使用了線程安全的AtomicInteger類來進行當前元素個數的計數工作,並與capacity容量進行比較。
AtomicInteger內部使用的是CAS操作來保證操作的原子性,CAS操作又涉及Unsafe類,是JVM調用的本地方法,使用了CPU的原語。
有待擴展