简体   繁体   中英

Synchronized methods and static variable access JAVA / ANDROID

I need help with some JAVA theory...

So I recently discovered that if an app uses multiple threads, and there is any possibility of different threads accessing the same shared variable at the same time, then one should use "synchronized" methods to get/set said variable.

So... in my (location aware) app, I have variables LAT, and LON that belong to the MainActivity and are static. They are accessed from background services like so:

appendToPOST(MainActivity.LAT);

And in MainActivity itself, I am using google play location services, and so in the onLocationChanged() callback method in MainActivity, I have:

LAT = [arbitrary Double value goes here];

So therefore, that means I should implement:

public static synchronized void setLAT(Double inLAT){

    LAT = inLAT;

}

public static synchronized void setLON(Double inLON){

    LON = inLON;

}

public static synchronized Double getLAT(){

    return LAT;

}

public static synchronized Double getLON(){

    return LON;

}

Correct? Thanks for any clarification/help.

Added: Also, should I change the code in the onLocationChanged() method to use the synchronized methods, even though it exists in the same class as the variable?

First, synchronized static methods are type of Java's built-in locks. They use class object as a lock, so only one thread at a time can work with the class. If one thread executing one of the methods, other threads cannot execute any of the objects methods. This is locking type of synchronization. It affects performance. But if high performance is not required, this solution will work. You need mark methods that read/change data with synchronized keyword.

Second, I assume your variables mean coordinates of location: latitude and longitude. If so, they must be accessed together. You can make new composite class. If they are not accessed at the same time, it can lead to race condition.

PS: let us know if synchronization affects performance. There are non-locking at a class level solutions.

Your change is correct so far. And as you already mentioned every access (local access as well) to these shared state variables must be using the synchronized accessors.

Furthermore, if the values of LAT and LON belong together (I assume you are representing a location with these values) you should make sure they can not be modified or retrieved independent of each other. That is you should not add a setter and getter for each value but one for both. And if these values belong together you could think of introducing a new class that represents both values like

public class Location {
    private double mLon;
    private double mLat;

    // Add getters and setters. These don't need to be synchronized
}

and change the synchronized accessors in MainActivity to

public static synchronized setLocation(final Location inLocation) {
    ...
}

Just for completeness using synchronized blocks is probably the most common but not the most efficient solution for implementing thread synchronization on shared state objects. If it comes to performance you should probably take a look at the classes in java.util.concurrent . See here for a short introduction of the Lock object.

UPDATE :
Updated answer with code example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM