說明
在使用LinkedBlockingQueue的offer方法時,出現了中斷異常,現分析一下出現這個中斷異常的原因。
會産生中斷異常的Demo
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class TestLinkedBlockingQueue {
public static void main(String[] args) {
LinkedBlockingQueue lbq = new LinkedBlockingQueue(3);
for(int i = 0; i < 10; i++){
try {
System.out.println(lbq);
//這裡用offer方法往阻塞隊列裡面添加對象,此方法表示若隊列滿了,則等待1秒,1秒後若隊列還是滿的,則丢棄資料。
lbq.offer(i, 1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread.currentThread().interrupt();//如果注釋掉這行代碼,則此程式不會抛出異常
}
}
}
LinkedBlockingQueue的offer源碼方法
public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
if (e == null) throw new NullPointerException();
long nanos = unit.toNanos(timeout);
int c = -1;
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
if (nanos <= 0)
return false;
nanos = notFull.awaitNanos(nanos);
}
enqueue(new Node<E>(e));
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
return true;
}
//lockInterruptibly方法
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
//acquireInterruptibly方法
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
是以,當線程被标記有中斷标志時,offer添加時将擷取不到鎖,直接抛出中斷異常。