如何在前台和后台进程之间同步访问sqlite数据库? [英] How to synchronize access to sqlite db between foreground and background process?

查看:219
本文介绍了如何在前台和后台进程之间同步访问sqlite数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在后台运行的服务,可以访问(读和写)sqlite数据库。相应的前台进程(主应用程序)也可以访问(读和写)sqlite数据库在我的Android应用程序。

I have a service that runs in the background which can access (read and write) to sqlite database. The corresponding foreground process (main app) can also access (read and write) to sqlite database in my android application.

如何防止与尝试访问/保存/读取/从sqlite db和正确的方法应该是这样做的?

How can i prevent problems related to trying to access / save / read at the same time to/from sqlite db and what should be the correct way to do this?

推荐答案

2个简单的方法做到这一点,第一个为ChirstopheCVB写:创建一个同步方法。同步方法只能由一个线程访问,其他线程只能被阻止。

There are 2 easy ways to do this, the first as ChirstopheCVB writes: Create a synchronized method. A synchronized method can only be accessed by one thread, other threads are blocked.

这是推荐的方法,因为它将所有DB访问相关代码放在一个地方。当您更改数据库的表布局时,您不需要搜索所有代码并进行调整。

This is the recommended method, as it keeps all DB access related code in a single place. When you ever change the table layout of your database, you do not need to hunt through all of your code and make adjustments. You 'hide' the details from your main thread.

如果你想保存你的数据库代码在主线程,然后使用信号量。在Java中有支持:
http:// developer .android.com / reference / java / util / concurrent / Semaphore.html

If you want to keep your db code in the main thread, then use semaphores. There is support for that in Java: http://developer.android.com/reference/java/util/concurrent/Semaphore.html

信号量是(简化)一个单一对象,表示某人是否正在访问共享资源(例如您的数据库)。在访问数据库之前,请检查您是否被允许,如果是,则设置对象以阻止其他对象。做你的事情和重置对象,以便其他人可以尝试访问资源。

A semaphore is (simplified) a single object indicating if somebody is accessing a shared resource (e.g. your DB). Before accessing the DB, check if you are allowed and if you are, then set the object so it blocks others. Do your thing and reset the objects so others can try to access the resource.

一个简单的例子,假设你有线程A&线程B和全局变量canUse。

A simple example, assume you have thread A & thread B, and a global variable 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个问题。首先,你阻塞你的线程,因为你正在等待资源可用。有一个风险,因为它可能永远不可用,你有死锁。

This works, but there are 2 problems. First, you are blocking your thread because you are waiting for the resource to become available. There is a risk, because it might never become available and you have deadlock.

第二个问题更严重。想象一下你有3个线程:A,B和C. C抓住了锁,A& B正在等待。以下是可能的

The second problem is more severe. Imagine you have 3 threads: A, B and C. C has grabbed the lock and both A & B are waiting. The following is possible

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;

上面的例子显示了检查变量和更改原子是如何重要。换句话说,没有什么可以发生。

Above example shows how important it is that checking the variable and changing it is done in an atomic way. In other words, nothing else can happen.

幸运的是,java为你提供了信号量。在开始时不容易理解,但是必须明白,如果你想要做没有使用同步方法的请求(这样的方法作为信号量为你没有额外的编码工作)。

Fortunately, java provides you with semaphores. It is not easy to understand in the beginning, but a must to understand if you want to do what you are asking for without using synchronized methods (such methods act as semaphores for you without extra coding effort).

这篇关于如何在前台和后台进程之间同步访问sqlite数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆