LinkedBlockingQueue的線程安全原因


 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的原語。

有待擴展

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM