LinkedBlockingQueue阻塞队列offer()操作抛出中断异常

简介:

说明

在使用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添加时将获取不到锁,直接抛出中断异常。

目录
相关文章
|
3月前
|
Java
线程池中线程抛了异常,该如何处理?
【8月更文挑战第27天】在Java多线程编程中,线程池(ThreadPool)是一种常用的并发处理工具,它能够有效地管理线程的生命周期,提高资源利用率,并简化并发编程的复杂性。然而,当线程池中的线程在执行任务时抛出异常,如果不妥善处理,这些异常可能会导致程序出现未预料的行为,甚至崩溃。因此,了解并掌握线程池异常处理机制至关重要。
378 0
|
6月前
|
存储 缓存 安全
Java线程池ThreadPoolExcutor源码解读详解05-阻塞队列之DelayQueue原理及扩容机制详解
DelayQueue` 是 Java 中的一个线程安全的阻塞队列,它用于存储实现了 `Delayed` 接口的元素,这些元素都有一个延迟时间。当元素的延迟时间过去之后,它们才能被从队列中取出。以下是摘要: 1. **核心特性**: - 基于 `PriorityQueue` 实现,元素按延迟时间排序,优先级高的先出队。 - 使用 `ReentrantLock` 和条件变量 `available` 控制并发。 - 只有延迟时间小于0的元素才能被取出。 - 不允许插入 `null` 元素。 2. **构造器**: - 默认构造器创建无初始元素的队列。 - 可以
94 5
|
算法 安全 Java
【阻塞队列BlockingQueue&非阻塞队列ConcurrentLinkedQueue&同步队列SyncQueue】
【阻塞队列BlockingQueue&非阻塞队列ConcurrentLinkedQueue&同步队列SyncQueue】
|
12月前
|
消息中间件
并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue使用场景总结
并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue使用场景总结
53 0
Java多线程:捕获线程异常
你处理过多线程中的异常吗?如何捕获多线程中发生的异常?捕获子线程的异常与捕获当前线程的异常一样简单吗?
|
消息中间件 JavaScript 小程序
线程池执行的用户任务抛出异常会怎样
线程池执行的用户任务抛出异常会怎样
|
存储 消息中间件 安全
堵塞队列BlockingQueue 使用与理解
堵塞队列本质就是队列,底层数据结构 通常是由数组,或者链表构成。实现FIFO思想 当阻塞队列是空时,从队列中获取元素的操作将会被阻塞。 当阻塞队列是满时,往队列里添加元素的操作将会被阻塞。
150 0
|
安全
阻塞队列中的安全中断
阻塞队列中的安全中断
184 0
阻塞队列中的安全中断