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的原语。
有待扩展