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