我有一个函数:fillFromDB
,它从 SQLite 数据库中填充一个名为 list
的 ArrayList
实例。
我还有另一个 Thread
,它应该清除 list
并重新填充它。
我在处理列表时遇到了一些问题,因为有时另一个 Thread
会清除列表,而第一个线程仍在填充它,从而导致适配器出现 IndexOutOfBoundsException
。
// This occurs onCreate()
fillFromDb(list);
downloadAndRepopulateList(list);
private void downloadAndRepopulateList(List list) {
new Thread(new Runnable() {
@Override public void run() {
list.clear();
// Some other clode
}
}
}
我知道问题是因为它们不是线程安全的,但我以前从未使用过synchronized
。
所以我的问题是:
如果我像这样更改下载功能:
private void downloadAndRepopulateList(List list) {
new Thread(new Runnable() {
@Override public void run() {
synchronized(list) {
list.clear();
// Some other clode
}
}
}
}
它会等待 UIThread 在 fillFromDb()
上完成填充列表,然后继续清除并重新填充它吗?
如果没有,我应该怎么做?
最佳答案
尽管我更愿意推荐使用 LinkedBlockingQueue
。即
list = new LinkedBlockingQueue<SomeType>();
fillFromDb(list);
downloadAndRepopulateList(list);
private void downloadAndRepopulateList(List list) {
new Thread(new Runnable() {
@Override public void run() {
list.clear();
// Some other clode
}
}
}
LinkedBlockingQueue将自己为您管理同步,您不需要持有任何锁等。
如果您希望使用Arraylist
来实现它,您必须将它从两侧设为原子。即要访问 list
,他们应该首先持有对象的锁并继续。如果其他人持有锁,则等待。
synchonized(list){
fillFromDb(list);
downloadAndRepopulateList(list);
}
private void downloadAndRepopulateList(List list) {
new Thread(new Runnable() {
@Override public void run() {
synhronized(list){
list.clear();
}
// Some other clode
}
}
}
关于android - 同步块(synchronized block)android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17794595/