开发者

There is a easy way to protect a variable to be accesed only by one thread at once?

i have a variable on my "SharedPreferences", that is accesed by two different threads, one in a service, and one in a activity.

There is a easy way to protect this variable to be accesed by two threads at once?

i need to protect this code:

            config开发者_如何学运维Editor.putString("mylatitude", ""+currentLocation.getLatitude());
            configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
            configEditor.commit();

i tryed with this but doesn't works:

Object LOCK = new Object();
                synchronized (LOCK){
                configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
                configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
                configEditor.commit();
                }

thanks


Object LOCK = new Object();


 synchronized (LOCK) {
     // lines of Java code that has to be thread safe
    }

EDIT: edit the code to be exactly for the situation when the code is modifying several variables and it has to be thread-safe. For a single variable (as is in the title of the question) lock the variable itself, you don't need a separate lock for it.


I'm not sure, but I believe using a Handler may be what you need. Take a look at this article, which explains when and how to use them. It also provides some code samples which may be helpful.


Try something like this:

public class MyClass {
    private final Object lock = new Object();

    public myMethod() {
        ...
        synchronized (lock) {
            // At most one thread is executing this
            // at the same time for this instance
        }
        ...
    }
}

The important thing is that the lock object should be an instance (and not local) variable, so that every thread uses the same lock for that particular instance of MyClass. Most of the time you want it to be final so that there is no posibility of changing it by mistake.

If you make the lock static, then at most one thread will be executing the synchronized section, no matter in which instance of MyClass.

EDIT:

For your particular case, you can adapt the following idea:

public class Service {
    public void doSomethingWithConfigEditor() {
        ConfigEditor configEditor = // get configEditor
        synchronized (configEditor) {
            // something with configEditor
        }            
    }    
}

public class Activity {
    public void doAnotherThingWithConfigEditor() {
        ConfigEditor configEditor = // get configEditor
        synchronized (configEditor) {
            // another thing with configEditor
        }            
    }
}

By synchronizing on configEditor, you guarantee that those two blocks of code never execute in parallel on the same instance of ConfigEditor.


This is typically done using critical sections aka mutexes. Before accessing the variable, your thread should aquire a lock on the mutex. While the mutex is locked, any attempt to aquire another lock will wait until the previous lock is released. This way, threads will wait for each other when accessing the variable.


You need to put the synchronized block in both locations that access the variable which you are trying to protect. Protecting it only one of the locations doesn't help.


Are you sure this is in two different threads? Your service code will only be running in a different thread if you are executing due to someone calling through to your IBinder interface from another process (or another thread in your own process).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜