【发布时间】:2012-12-24 13:30:06
【问题描述】:
我有一个SQLiteOpenHelper 类,它实现了单例模式并具有三个方法:addLogs()、getLogs() 和deleteLogs()。七个线程(由 BroadcastReceiver 在某些调度下触发)访问数据库——其中六个只使用addLogs(),另一个使用getLogs() 并在完成之前调用deleteLogs()。
我的问题是,因为最后一个线程对 SQLite 数据库进行了两次不同的调用,所以其他线程甚至可以在调用 deleteLogs() 之前调用 addLogs(),这会破坏我的输出。如何让一个线程将两个对 SQLiteOpenHelper 的调用视为单个原子事务?
我尝试过:在SQLiteOpenHelper 中创建一个静态ReentrantLock 成员,并在事务前后从七个线程中的每个线程调用lock() 和unlock()。即使最后一个线程仍然拥有锁,其他六个线程仍然可以通过,它在getLogs() 之前调用并在deleteLogs() 之后释放。
更新:这是访问这两种方法的第七个线程。
public class Uploader extends Thread {
private Context context;
public Uploader(Context context) {
this.context = context;
}
@Override
public void run() {
Logger.d("STARTED: Uploader");
DB db = DB.getInstance(context);
List<JsonLog> logs = db.getLogs(); // FIRST CALL
String json = new Gson().toJson(logs); // convert to JSON
// connect to the server and upload
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(This.URL);
post.setHeader("content-type", "application/json");
try {
Logger.d("to upload: " + json);
StringEntity se = new StringEntity(json);
post.setEntity(se);
StatusLine status = client.execute(post).getStatusLine();
// if upload is successful
if (status.getStatusCode() == HttpStatus.SC_OK) {
db.deleteLogs(); // SECOND CALL
} else {
Logger.d("Uploader failed. " + status.getStatusCode() + ": " + status.getReasonPhrase());
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.d("FINISHED: Uploader");
}
}
【问题讨论】:
标签: java android multithreading sqlite concurrency