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);            
        }
    }
});
4

3 回答 3

3

为了尽量减少重新发明轮子,您可以将其实现为生产者/消费者同步。对于初学者:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ArrayBlockingQueue.html

以防万一,这里有一些介绍性的东西:

http://en.wikipedia.org/wiki/Producer-consumer_problem

于 2012-12-10T09:50:07.887 回答
2

你的问题有两个方面。

  • 假设这sData是一个局部变量,那么要让两个线程共享数组,您只需声明sDatafinal. (如果sData是一个实例或类变量,你甚至不需要这样做......)

  • 让两个线程安全地共享数组有点困难。问题是两个线程需要同步。发送线程需要知道记录线程已写入数组的哪一部分。此外,同步对于确保记录线程写入的数据对发送线程可见是必要的。

在这个例子中,正确的同步很可能需要几个额外的变量来指示两个线程的当前位置。而且由于您必须处理一个线程需要等待另一个线程添加或发送数据的情况,您可能需要使用Object.wait()Object.notify()避免忙等待。


但是你在语义级别上所做的看起来好像它需要像经典的循环short值缓冲区一样操作。所以我建议寻找一个可以重用的现有实现。(例如,如果您愿意承担Shortvs的开销,short那么您可以使用ArrayBlockingQueue<Short>.)

于 2012-12-10T09:36:15.547 回答
0

处理此问题的一种方法是,如果这是一次性操作,则使用闩锁;如果需要重复,则使用CyclicBarrier 。

于 2012-12-10T10:03:41.700 回答