从Arraylist中删除第0个元素时出现IndexOutOfBoundsException

时间:2018-08-23 11:09:44

标签: java android multithreading arraylist

我已经使用ArrayList来存储(作为队列)通过BLE接收的数据。而且我使用相同的ArrayList将数据传递给Bufferedwriter。每次我通过调用.remove(0)方法来验证ArrayList为非空后,调用.isempty()方法来获取第一个元素。请在下面找到代码示例。

while (!ppgHighQueue.isEmpty()) {
    try {
        PPG ppg_record = ppgHighQueue.remove(0);
        if (ppg_record != null) {
            ppg_400Hz_record.write(ppg_record.toString());
            ppg_400Hz_record.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是从这一点来看,很少会出现以下异常并导致应用崩溃。

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

是否还有其他可行的方法来存储数据而不是使用ArrayList?

1 个答案:

答案 0 :(得分:2)

您的代码不是线程安全的。如果从多个线程访问ppgHighQueue,则可以在isEmpty()remove(0)调用之间进行修改。

您应该考虑同步ppgHighQueue访问。

简化示例:

class SomeWorker {


    ArrayList ppgHighQueue;
    Object lock = new Object();

    void remover() {
        while (!ppgHighQueue.isEmpty()) {
            synchronized (lock) {
                try {
                    if (ppgHighQueue.isEmpty()) continue; // this check after lock is needed
                    PPG ppg_record = ppgHighQueue.remove(0);
                    if (ppg_record != null) {
                        ppg_400Hz_record.write(ppg_record.toString());
                        ppg_400Hz_record.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    void otherAccess() {
        synchronized (lock) {
            if (!ppgHighQueue.isEmpty()) {
                ppgHighQueue.remove(0);
            }
        }
    }
}

第二项isEmpty检查确保获取锁定后您的列表不为空。