我有一个在其中可以访问(读取和写入)到SQLite数据库后台运行的服务。 相应的前台进程(主应用程序)也可以访问我的Android应用程序(读,写)到SQLite数据库。
如何防止与试图访问的问题/保存/在同一时间读取/从sqlite的分贝应该是什么这样做的正确方法?
我有一个在其中可以访问(读取和写入)到SQLite数据库后台运行的服务。 相应的前台进程(主应用程序)也可以访问我的Android应用程序(读,写)到SQLite数据库。
如何防止与试图访问的问题/保存/在同一时间读取/从sqlite的分贝应该是什么这样做的正确方法?
有2层简单的方法可以做到这一点,首先是ChirstopheCVB写道:创建一个同步的方法。 一个同步方法只能由一个线程访问,其他线程被阻塞。
这是推荐的方法,因为它保持在一个地方相关的代码全部DB访问。 当你改变数据库的表布局,你并不需要通过所有代码的追捕,并作出调整。 你“隐藏”从你的主线程的详细信息。
如果你想保持你的数据库的代码在主线程,然后使用信号。 还有是在Java支持: http://developer.android.com/reference/java/util/concurrent/Semaphore.html
信号量是(简化的),其指示如果有人正在访问一个共享资源(例如,你的DB)的单个对象。 访问数据库之前,请检查您是否是允许的,如果你是,那么设置对象,以便它阻止其他人。 做你的事,并重置对象,以便其他人可以尝试访问该资源。
一个简单的例子,假设你有线程A和线程B,和一个全局变量canUse。
Init: canUse = true;
Thread A:
while (!canUse) wait; // busy waiting, your thread is blocked
canUse = false; // canUse was true, now we grab access.
do our thing;
canUse = true; // Others are allowed to use the resource again.
线程B看起来是一样的。
这工作,但也有2个问题。 首先,你是阻止您的线程,因为你正在等待资源可用。 是有风险的,因为它可能永远不会变得可用,你必须僵局。
第二个问题更为严重。 想象一下,你有3个线程:A,B和C C已抓住了锁,A和B都在等待。 以下是可能的
A: while (!canUse) wait;
B: while (!canUse) wait;
C: canUse = true;
A: Hooray, we can grab the resource
B: Hooray, we can grab the resource
A: canUse = false;
B: canUse = false;
上面的例子说明它是多么重要的是检查变量和更改它以原子的方式进行。 换句话说,没有别的可能发生。
幸运的是,Java提供你旗语。 这是不容易在一开始就明白,但必须明白,如果你想要做你问什么不使用synchronized方法(这些方法作为信号灯为您无需额外的编码工作)。