android - 同步块(synchronized block)android

标签 android multithreading synchronized

我有一个函数:fillFromDB,它从 SQLite 数据库中填充一个名为 listArrayList 实例。

我还有另一个 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/

相关文章:

安卓软键盘会无缘无故隐藏

C# 控制线程(恢复/挂起)

java - 1 java内存刷新 volatile : A good programdesign?

java - java中同步块(synchronized block)之后的代码

android - 在 Android Studio 中构建应用程序之前自动运行测试

android - AutoCompleteTextView onItemClick 使用 HashMap 的项目位置或 id

c# - System.Data.SQLite for .NET 中的序列化模式

C#:如果多个线程只读取它,我是否必须使 ArrayList 同步

java - 同步(对象) { } 问题

java - 如何获取谷歌地图的中心点?