Java线程并发读写

时间:2013-07-17 12:47:15

标签: java android multithreading concurrency

我有一个arraylist存储我收到的数据并通过蓝牙异步传输。

我有一个写线程和一个读取线程来访问arraylist。我正在尝试模拟蓝牙回声(蓝牙是回应我发送的所有内容)。

private class ReadThread extends Thread {
@Override
public void run() {
    super.run();
        while(!isInterrupted()) {

            try {
                byte[] buffer = new byte[64];
                if (mInputStream == null) return;
                size = mInputStream.read(buffer);
                if (size == 64) {
                    if (bufferList.isEmpty()){
                        Log.i("AOK Fail","Nothing to AOK");
                    }

                    if (compareByte(buffer,bufferList.get(0) == true) // Compare data in this 2 byte array
                          bufferList.remove(0);
                }
            } catch (IOException e) {
            e.printStackTrace();
            return;
        }
    }
}
}

private class WriteThread extends Thread {
    @Override
    public void run() {
    super.run();
    while(!isInterrupted()) {

        try {
            count++;
            if (bufferList.isEmpty() == false && count < 3){    
                write(bufferList.get(0));       
                count = 0;
            }else{
                // Drop data after 3 fail attempt
                bufferList.remove(0);
                count=0;
            }               

            Thread.sleep(500);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
    }
}
}

按下按钮,我将发送数据。如果我慢慢传输,它工作正常。但是当我开始快速点击(队列数据传输)时它失败了。一旦我收到AOK失败消息。即使是新添加的数据,所有剩余数据都将是AOK Fail。为什么会如此

如果是线程问题,在发送所有数据后是不是应该解决?

2 个答案:

答案 0 :(得分:1)

这个bufferList变量是一个线程安全对象吗?像一个数组阻止列表或什么?如果不是,您可能在尝试同时添加/删除它时遇到一些问题。

这会导致生产者线程中出现异常,没有其他任何东西可以传输给你,并且没有任何东西可以让AOk&#34;日志中。

答案 1 :(得分:1)

这段代码的工作原理并不十分清楚,因为它不包含一些细节:

  • 你如何喂养bufferList,哪种类型?也许您在问题中提到的ArrayList? ArrayList不是线程安全的,请参阅ArrayList documentation for Android
  • write方法的作用是什么?
  • compareByte方法的作用是什么?这似乎是显而易见的,但是看看代码是很好的,你知道,以防万一(你也错过了一个括号)。
  • 您在WriteThread类中声明的count var在哪里?您是否在此代码之外增加count值?如果这是真的,那么在bufferList(否则阻止)时,您可能会从count >= 3变量中删除所有内容。如果您这样做,bufferList.isEmpty() == false && count < 3条件的第一部分可能会在某个时间出现错误,因为您的bufferList将为空;然后你将执行else块,试图从空ArrayList中删除一个元素,你的代码将抛出一个IndexOutOfBoudsException(参见ArrayList remove method documentation),你的WriteThread将被中止。