【发布时间】:2012-10-05 10:14:40
【问题描述】:
我是 android 编程新手,之前没有深入研究过 java。我真的很困惑如何使用synchronized 来确保static variables 上的线程安全:
我通常创建一个名为Utils 的类,其中包含一些static functions,这是我所有其他类大部分时间都需要的。这是将重复代码排除在我的课程之外的正确方法吗?
我总是遇到使用数据库的问题。当我为某个数据库创建 sqliteHelper 类并尝试从 Activity 和后台服务管理该数据库时,我通常会得到 陷入麻烦。如果我使用辅助类的本地对象,当两个辅助对象尝试一起获取写锁时,我最容易陷入数据库死锁。
为了摆脱这个麻烦,我在我的utils 类中创建了一个帮助类的static 实例。现在,为了对数据库执行任何操作,我的活动和服务执行以下操作:
public class Utils{
public static MDatabaseHelper mHelper;
public static void instantiateHelper(Context context){
if(mHelper==null)
mHelper=new MDatabaseHelper(context);
}
}
public class mActivity extends Activity{
public void insert some item in database(final Item item) // this method is called in the Activity at some time
(new Thread(){
@Override public void run(){
Utils.instantiateHelper(getBaseContext());
mHelper.insertItem(item); }
}).start();
}
public class mService extends Service{
public void insert some item in database(final Item item) // this method is called in the service at some time
(new Thread(){
@Override public void run{
Utils.instantiateHelper(getBaseContext());
mHelper.insertItem(item); }
}).start();
}
现在,如果服务和活动都尝试将项目插入在一起会怎样。我经常遇到这种情况并发生错误。 为了避免这种情况,我使用了这个解决方法:
我将插入操作放在 try 块中,失败时我等待随机时间再试一次
public void insertSomeItemInDatabase(final Item item)
(new Thread(){
@Override public void run(){
int i=0;
Random rand=new Random();
while(true){
if(i>10)
return;
try{
Utils.instantiateHelper(getBaseContext());
mHelper.insertItem(item);
break;
}catch(Exception e){
i++;
try{
Thread.sleep(rand.nextInt(1000));
}catch(Exception e){}
}
}
}
}
}).start();
}
我知道这是同步的最差方法,但由于我对java 很陌生,任何人都可以解释一下如何在这个场景中使用synchronized。
谢谢
【问题讨论】:
-
为什么您的 insertSomeItemInDatabase 没有同步?
-
仅供参考:您的方法是网络协议中的常用方法。它有点类似于Aloha Protocol。如果你想坚持这种方法,你可能想申请exponantial back off。
-
我对同步静态变量了解不多。一个代码 sn-p 和解释将是一个很大的帮助@njzk2
-
当两个帮助对象尝试一起获取写锁时,“进入数据库死锁”是什么意思。如果你只有一把锁,就没有机会出现死锁情况,你需要不止一把锁。
-
没有什么是静态的。只需将 synchronized 放在您的 insertItem 方法的声明中。这意味着一次只有一个线程可以访问它,其他线程正在排队等待。
标签: java android concurrency synchronized android-sqlite