在BlockingQueue上同步线程操作

时间:2013-02-28 21:49:29

标签: java android multithreading synchronized blockingqueue

我正在开发一个Android项目,其中来自源的数据使用opengl呈现给用户,为了使其工作,我使用Thread从源读取数据,然后将这些数据存储在BlockingQueue上FIFO,然后弹出GLRenderer线程上的数据。我使用BlockingQueue来处理生产者/消费者场景。

只要向用户呈现只有一种类型的数据,一切正常。

例如,假设我必须使用数据类型,DATA A和DATA B,这两种类型都是从同一个源读取并使用Id标记选择的。为了独立处理每种数据类型,我使用了2个阅读线程。这些线程访问相同的对象方法当然是同步的以避免干扰,然后读取的数据分别存储在BlockingQueue A和BlockingQueue B上,并由GLRenderer A和GLRenderer B读取以同时显示2种类型的数据。屏幕。

我目前面临的问题是,数据A以随机方式与数据B交换,因此几乎不可能在屏幕上分别看到两种类型的数据。

以下是每个相关块的代码。

ReadingTask:

private class ReadDataTask extends AsyncTask<Void, Void, Void> {

    private BlockingQueue<short[]> mFIFO;
    private byte mDeviceID;
    private boolean mIsDataShifted;

    public ReadDataTask(BlockingQueue<short[]> fifo, byte deviceID, boolean shiftData) {
        mFIFO = fifo;
        mDeviceID = deviceID;
        mIsDataShifted = shiftData;
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            while(true) {
                if(isCancelled())
                    return null;

                mFIFO.put(mCAL.readData(mDeviceID, mIsDataShifted));

                Log.i("COM", "Thread " + mId + ":Reading...");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            return null;
        }
    }
}

希望你能帮助我。

更新

我发现我的问题存在一些混淆,所以我会试着澄清更多的问题。

“阅读任务”是上面提到的AsyncTask,通过这个任务,我从一个名为“Source”的IO端口获取了一些数据。对于读取IO端口的每个线程,对象mCAL是相同的,并且其类的方法都是同步的(例如,读取和写入不能同时发生)。 mDeviceID和mIsDataShifted字段作为参数传递,用于AsyncTask先前执行的初始化,“Reading Task”的每个实例使用mDeviceID和mIsDataShifted的不同值。 BlockingQueue mFIFO也作为参数传递给“ReadingTask”,并且对于此Thread的每个实例都是不同的。所以基本上我有2个OpenGL线程实例,2个ReadingTask线程实例和1个mCAL对象实例,它们在当前运行的所有可能“ReadingTasks”之间共享。

另外,我做了一些测试,我注意到每次“ReadingTask”线程的一个实例连续多次调用mCAL.readData()方法时,数据从一个OpenGL视图交换到另一个,所以我想这个问题涉及BlockingQueue FIFO put()方法(也许它必须在同步方法中调用?)。

这是CAL_Interface类:

public class CAL_Interface {

static
{
    System.loadLibrary("FPGA_USB");
    System.loadLibrary("CAL");
}

/**
 * Set the properties for the data acquisition, such as the length of the data to
 * acquire and the sampling frequency at which the data is being processed.
 * 
 * @return
 */
public native int setAcquisitionProperties(int dataLength, double samplingFreq);

/**
 * Configure the USB Chip and program the FPGA (if possible).
 * 
 * @param fpgaModel
 * @return
 */
public native int configureUSB(int fpgaModel);

/**
 * Initialize the USB Channel.
 * 
 * @return
 */
public native int initUSBChannel();

/**
 * Send a SCPI Command to configure the Hardware Registers.
 * 
 * @param cmd       SCPI Command.
 * @param deviceID  Device Identifier.
 * 
 * @return          Error Flag: 0 when success. 1 when error.
 * 
 */
public native int sendCommand2FPGA(String cmd, byte deviceID);

/**
 * Set the capture mode. For instance, choose between Oscilloscope data or
 * Spectrum Analyzer data.
 * 
 * @param config
 * @return
 */
public native int setCaptureMode(byte config);

/**
 * Receives the Device-Specific Data generated by the FPGA.
 * 
 * @return          Array containing the data.
 */
public native short[] getDataFromFPGA(byte deviceID, boolean shiftData);

/**
 * Closes the USB Channel so the device can be properly de-initialized.
 * 
 * @return
 */
public native int deinitUSBChannel();   

/**
 * Set the Internally Generated Signals Attributes
 * 
 * @param channel
 * @param amplitude
 * @param frequency
 * @return
 */
public native int setInternalSignalAttr(byte channel, byte wave, byte amplitude, double frequency);

public synchronized void openCommunicationChannel(int fpgaModel) {
    /* Set the native constants for internal calculations */
    setAcquisitionProperties(1024, 1e9);
    /* Configure the USB Chip CyFX2 */
    configureUSB(fpgaModel);
    /* Initialize the USB Channel */
    initUSBChannel();
}

public synchronized void closeCommunicationChannel() {
    /* De-initialize the USB Channel */
    deinitUSBChannel();
}

public synchronized short[] readData(byte deviceID, boolean shiftData) {
    return getDataFromFPGA(deviceID, shiftData);
}

public synchronized void writeData(byte deviceID, String cmd) {
    sendCommand2FPGA(cmd, deviceID);
}
}

此致

0 个答案:

没有答案