如何在两个线程之间共享一个对象(线程同步)?

4

我有两个线程。一个将音频数据记录到变量中。另一个线程将记录的变量发送到服务器。考虑到我是多线程新手,我需要在并发方面做些什么?

以下是代码片段:

short[] sData = new short[1024];

recordingThread = new Thread(new Runnable() {
        public void run() {
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
            while (isRecording) {
                recorder.read(sData, 0, BufferElements2Rec);
            }

        }
    }, "AudioRecorder Thread");
    recordingThread.start();

还有一个线程正在访问相同的sData并将其发送到服务器:

Thread sendThread= new Thread(new Runnable() {
    public void run() {
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
    while (true) {
        try {

      ByteBuffer.wrap(bData).order(ByteOrder.LITTLE_ENDIAN)
            .asShortBuffer().put(sData);            
        }
    }
});

你可以将你的数组标记为 final static - waqaslam
应该在Android上使用AsyncTask :) - Anders Metnik
1
@AndersMetnik 使用AsyncTask会导致更多的延迟。它的工作方式类似于一个请求对应一个响应。 - Rahul Baradia
2
你应该使用“原子操作”或“同步化”。 - QuokMoon
@TechEnd 不好意思,我没看到它是连续的 :/ - Anders Metnik
3个回答

3

2
你的问题有两个方面。
1. 假设`sData`是一个局部变量,你只需要将其声明为`final`即可使两个线程共享该数组。(如果`sData`是一个实例或类变量,则不需要这样做。)
2. 安全地让两个线程共享数组比较困难。问题在于两个线程需要同步。发送线程需要知道记录线程写入了哪部分数组。此外,同步必要以确保记录线程写入的数据对发送线程可见。
在这个例子中,合适的同步很可能需要一些额外的变量来指示两个线程的当前位置。由于需要处理一个线程等待另一个线程添加或发送数据的情况,因此您可能需要使用`Object.wait()`和`Object.notify()`以避免繁忙等待。
但是从语义层面上看,你正在进行的操作似乎需要像经典的`short`值循环缓冲区一样运行。因此,我建议您寻找现有的实现并重用它。(例如,如果你愿意承担`Short`与`short`之间的开销,那么你可以使用`ArrayBlockingQueue`。)

@Stephen... 是的,你说得对,我必须使用wait()和notify()方法来解决这个问题。 - G M Ramesh

0

处理这个问题的一种方法是,如果这是一次性操作,可以使用 latch,如果需要重复执行,则可以使用 CyclicBarrier


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接