开发笔记——LinkedBlockingQueue

最近工作上收到一个测试问题,在小米4等部分机型上应用容易闪退。然后查到原因是内存溢出,这里记录一下。

错误信息:

这里写图片描述

然后定位到GL2JNIView这个类
这里写图片描述
根据错误信息可以知道是创建线程时出现内存溢出,然后再看一下YUVThread

    class YUVBufferThread extends Thread {
        private YUVBuffer yuvBuf;
        private boolean isStopThread;

        public void stopThread(){
            isStopThread = true;
        }

        @Override
        public void run() {
            while (GL2JNIView.this.startReceiveBuf && !this.isStopThread) {
                try {
                    if (mBufQueue != null){
                        yuvBuf = mBufQueue.take();
                    }
                    if (yuvBuf != null) {
                        synchronized (lockObj) {

                            if (!m_is3d) {
                                if (y != null && u != null && v != null) {
                                    GL2JNIView.this.y.clear();
                                    GL2JNIView.this.u.clear();
                                    GL2JNIView.this.v.clear();
                                    yuvBuf.buf.position(0);
                                    yuvBuf.buf.get(yByteArr, 0, yByteArr.length);
                                    yuvBuf.buf.get(uByteArr, 0, uByteArr.length);
                                    yuvBuf.buf.get(vByteArr, 0, vByteArr.length);

                                    yuvBuf.buf.position(0);
                                    GL2JNIView.this.y.put(yByteArr, 0, yByteArr.length);
                                    GL2JNIView.this.u.put(uByteArr, 0, uByteArr.length);
                                    GL2JNIView.this.v.put(vByteArr, 0, vByteArr.length);
                                }
                            } else {
                                int size = yuvBuf.buf.limit();
                                if (m_disOld != true && yuvByteArr != null /*&& size>=yByteArr.length+uByteArr.length+vByteArr.length*/)//m_disOld
                                {
                                    yuvBuf.buf.position(0);
                                    yuvBuf.buf.get(yuvByteArr, 0, yByteArr.length + uByteArr.length + vByteArr.length);
                                    yuvBuf.buf.position(0);
                                } 
                            }
                            yuvBuf = null;
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

问题在这行代码:
yuvBuf = mBufQueue.take();
这里使用了一个LinkedBlockingQueue队列不断的取出YUV数据,这里使用take()方式取数据就出现了问题,当队列里面没有元素时,它会阻塞线程从而导致线程不能退出。
下面贴一下take的源码:

/**
     * Retrieves and removes the head of this queue, waiting if necessary
     * until an element becomes available.
     *
     * @return the head of this queue
     * @throws InterruptedException if interrupted while waiting
     */
    E take() throws InterruptedException;

除了take方法,还有poll方法,同样看一下源码注释:

/**
     * Retrieves and removes the head of this queue, waiting up to the
     * specified wait time if necessary for an element to become available.
     */
    E poll(long timeout, TimeUnit unit)
        throws InterruptedException;

这个方法能设置阻塞时间,所以这里使用poll方法代替take就能解决问题了。

总结##

在开发中要多去看源码,这样我们才能更好的理解没一个方法的作用,从而使用正确的Api来实现我们的需求。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值