Java 安卓同步的OnSensorChange?

Java 安卓同步的OnSensorChange?,java,android,multithreading,synchronization,android-sensors,Java,Android,Multithreading,Synchronization,Android Sensors,以下是我的问题: 我很难理解我的应用程序的同步方法 我轮询传感器,并在传感器值发生变化时将其存储到阵列中 float[] accelerometerMatrix = new float[3]; float[] accelerometerWorldMatrix = new float[3]; float[] gyroscopeMatrix = new float[3]; float[] gravityMatrix = new float[3]; float[] magneticMatrix = n

以下是我的问题:

我很难理解我的应用程序的同步方法

我轮询传感器,并在传感器值发生变化时将其存储到阵列中

float[] accelerometerMatrix = new float[3];
float[] accelerometerWorldMatrix = new float[3];
float[] gyroscopeMatrix = new float[3];
float[] gravityMatrix = new float[3];
float[] magneticMatrix = new float[3];
float[] rotationMatrix = new float[9];

class InsertHandler implements Runnable {
        public void run() {
            //get values from arrays and insert into db
        }
    }

public void onSensorChanged(SensorEvent event) {
        sensor = event.sensor;

        int i = sensor.getType();
        if (i == MainActivity.TYPE_ACCELEROMETER) {
            accelerometerMatrix = event.values;
        } else if (i == MainActivity.TYPE_GYROSCOPE) {
            gyroscopeMatrix = event.values;
        } else if (i == MainActivity.TYPE_GRAVITY) {
            gravityMatrix = event.values;
        } else if (i == MainActivity.TYPE_MAGNETIC) {
            magneticMatrix = event.values;
        }

        long curTime = System.currentTimeMillis();
        long diffTime = (curTime - lastUpdate);

        // only allow one update every POLL_FREQUENCY.
        if(diffTime > POLL_FREQUENCY) {
            lastUpdate = curTime;

            //insert into database in background thread
            executor.execute(insertHandler);
        }
    }
每隔10毫秒,我的应用程序将获取当前传感器值(来自阵列),并使用单线程执行器将其插入数据库。因此,
onSensorChanged
方法既向数组写入数据,又从数组中读取数据以写入数据库

我的问题是,是否应该同步
onSensorChanged
方法?

最重要的是我不会错过任何数据。每隔10毫秒,我需要存储当前传感器的值-不能遗漏任何值

因此,据我所知,同步方法意味着UI线程将持有锁,并将传感器值写入阵列。在此期间,由于锁定,执行器线程无法读取这些数组。然后解除锁,然后执行器线程锁定、从数组读取、写入数据库并释放锁

我可能会误解这里使用的同步方法,特别是考虑到
onSensorChanged
是事件驱动的,我不确定这是如何发挥作用的

但在这种情况下,我可能不会每隔10毫秒插入最新的值。当UI线程建立锁时,执行器线程无法将这些值写入数据库。当执行器线程可以写入时,这些值现在已经有几毫秒了,而且不准确

另一方面,同步意味着UI线程不会更改数组值,而同时执行线程会将更改一半的值插入数据库


因此,在这种情况下,我需要每隔10毫秒插入最新/准确的传感器数据,我是否应该使用同步方法?

您当前的代码不是线程安全的,因为
Runnable
使用的数组与UI线程写入的数组相同。一旦调用
executor.execute(insertHandler)
Runnable
将某个数组值写入数据库之前,不能保证UI线程不会获得另一个传感器事件并更改其中一个数组值。看来你理解这一部分

要解决这个问题,我不建议使用同步块,因为当
diffTime>POLL\u FREQUENCY
时,您似乎只想写出数组中存储的任何值。
onSensorChanged(…)
方法本身只会在代码中的UI线程上调用,因此您不必担心在使用此方法时另一个线程会更改数组的值

说到这里,您可以做的就是将数组的当前值存储在
Runnable
类的新实例中。我知道你在上一篇文章中建议使用相同的实例,但这不会产生明显的区别。您甚至可以打开Android监视器进行验证,并在应用程序运行时检查内存使用情况。通过存储当前值,在写入数据之前是否再次调用
onSensorChanged()
,现在就无关紧要了,因为您已经拥有了所需数据的一个不会更改的副本

以下是我在代码中的建议:

class InsertHandler implements Runnable {
    final float[] accelerometerMatrix;
    final float[] accelerometerWorldMatrix;
    final float[] gyroscopeMatrix;
    final float[] gravityMatrix;
    final float[] magneticMatrix;
    final float[] rotationMatrix;

    public InsertHandler(float[] accelerometerMatrix, float[] accelerometerWorldMatrix,
            float[] gyroscopeMatrix, float[] gravityMatrix,
            float[] magneticMatrix, float[] rotationMatrix) {
        this.accelerometerMatrix = accelerometerMatrix;
        this.accelerometerWorldMatrix = accelerometerWorldMatrix;
        this.gyroscopeMatrix = gyroscopeMatrix;
        this.gravityMatrix = gravityMatrix;
        this.magneticMatrix = magneticMatrix;
        this.rotationMatrix = rotationMatrix;
    }

    public void run() {
        // use class field arrays values and insert into db
    }
}
然后,将
Runnable
添加到
executor
时,请使用:

Runnable insertHandler = new InsertHandler(accelerometerMatrix, accelerometerWorldMatrix,
        gyroscopeMatrix, gravityMatrix, magneticMatrix, rotationMatrix);
executor.execute(insertHandler);