synchronized块android

时间:2013-07-22 18:19:37

标签: android multithreading synchronized

我有一个函数:fillFromDB,它填充SQLite DB中名为ArrayList的{​​{1}}个实例。

我还有另一个list,可以清除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

是否会等待UIThread完成填写private void downloadAndRepopulateList(List list) { new Thread(new Runnable() { @Override public void run() { synchronized(list) { list.clear(); // Some other clode } } } } 上的列表,然后继续清除并重新填充它?

如果没有,我应该怎么做?

2 个答案:

答案 0 :(得分:5)

虽然我宁愿推荐使用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
    }
}
}

答案 1 :(得分:1)

要使其正常运行,您还必须在fillFromDb方法上进行同步。所以最后你将有两个同步的部分,一个同步你的列表填充和另一个同步清除列表。您也可以将列表用作互斥锁,但我建议您将单独的对象用作互斥锁,我可以像Object mutex = new Object();一样。