【问题标题】:Java Thread Concurrent Read and WriteJava 线程并发读写
【发布时间】:2013-07-17 12:47:14
【问题描述】:

我有一个数组列表,用于存储我接收到的数据并通过蓝牙异步传输。

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

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 Fail 消息。所有剩余的数据都将 AOK Fail 即使是新添加的数据。为什么会这样

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

【问题讨论】:

  • bufferList 和 count 是如何声明的?从我所看到的来看,它们看起来并没有正确同步......

标签: java android multithreading concurrency


【解决方案1】:

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

这将导致生产者线程中的异常,不会传输任何其他内容,您将获得“Nothing to Aok”日志。

【讨论】:

    【解决方案2】:

    这段代码的工作原理不是很清楚,因为它没有包含一些细节:

    • bufferList 的喂养方式如何?它的类型是什么?也许您在问题中提到的 ArrayList ? ArrayList 不是线程安全的,请参阅ArrayList documentation for Android
    • write 方法有什么作用?
    • compareByte 方法有什么作用?这似乎很明显,但最好看看代码,以防万一(你也缺少括号)。
    • 您在WriteThread 类中使用的count 变量在哪里声明?您是否在此代码之外增加 count 值?如果这是真的,您可能会在count &gt;= 3 (其他块)时从bufferList 变量中删除所有内容。如果你这样做,你的bufferList.isEmpty() == false &amp;&amp; count &lt; 3 条件的第一部分有时可能是假的,因为你的bufferList 将是空的;然后您将执行 else 块,尝试从空的 ArrayList 中删除一个元素,您的代码将抛出 IndexOutOfBoudsException(请参阅ArrayList remove method documentation)并且您的 WriteThread 将被中止。

    【讨论】: