我的“SharedPreferences
”上有一个变量,有两个不同的线程,一个在服务中,一个在一个活动中。
有一种简单的方法可以保护这个变量一次被两个线程加入吗?
我需要保护这段代码:
configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
configEditor.commit();
我试过这个但是不起作用:
Object LOCK = new Object();
synchronized (LOCK){
configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
configEditor.commit();
}
感谢
答案 0 :(得分:6)
Object LOCK = new Object();
synchronized (LOCK) {
// lines of Java code that has to be thread safe
}
编辑:在代码修改多个变量并且必须是线程安全的情况下编辑代码以准确处理该情况。对于单个变量(如问题标题中所示)锁定变量本身,您不需要单独的锁定。
答案 1 :(得分:1)
尝试这样的事情:
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
}
...
}
}
重要的是,lock对象应该是一个实例(而不是本地)变量,因此每个线程对MyClass的特定实例使用相同的锁。大多数时候你希望它是final
,这样就没有错误地改变它的可能性。
如果你进行了锁static
,那么无论在哪个MyClass实例中,最多只有一个线程将执行synchronized
部分。
修改强>
对于您的特定情况,您可以调整以下想法:
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
}
}
}
通过在configEditor上进行同步,可以保证这两个代码块永远不会在同一个ConfigEditor实例上并行执行。
答案 2 :(得分:1)
我不确定,但我相信使用Handler可能就是您所需要的。 看看this article,它解释了何时以及如何使用它们。它还提供了一些可能有用的代码示例。
答案 3 :(得分:0)
这通常使用关键部分即互斥量来完成。在访问变量之前,您的线程应该获取互斥锁的锁定。当互斥锁被锁定时,任何获取另一个锁的尝试都将等到上一次锁被释放。这样,线程在访问变量时将相互等待。
答案 4 :(得分:0)
您需要将synchronized
块放在访问您要保护的变量的两个位置。仅保护其中一个位置无济于事。
答案 5 :(得分:0)
你确定这是两个不同的主题吗?如果由于某人从另一个进程(或您自己的进程中的另一个线程)调用IBinder接口而执行,您的服务代码将仅在不同的线程中运行。