我有一个ArrayList
,它在后台线程中被实例化并填充数据(我用它来存储Cursor
数据)。同时,它可以在主线程上被访问并使用foreach迭代。所以这显然可能会导致抛出异常。
我的问题是,如何最好地使这个类成为线程安全的字段,而不需要每次复制它或使用标志?
class SomeClass {
private final Context mContext;
private List<String> mList = null;
SomeClass(Context context) {
mContext = context;
}
public void populateList() {
new Thread(new Runnable() {
@Override
public void run() {
mList = new ArrayList<>();
Cursor cursor = mContext.getContentResolver().query(
DataProvider.CONTENT_URI, null, null, null, null);
try {
while (cursor.moveToNext()) {
mList.add(cursor.getString(cursor.getColumnIndex(DataProvider.NAME)));
}
} catch (Exception e) {
Log.e("Error", e.getMessage(), e);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}).start();
}
public boolean searchList(String query) { // Invoked on the main thread
if (mList != null) {
for (String name : mList) {
if (name.equals(query) {
return true;
}
}
}
return false;
}
}
CopyOnWriteArrayList
,但是OP说“不要复制”。也许他想保证“只有一个线程可以同时运行受保护的块”。 - beatngu13null
。使用Vector
不能防止ConcurrentModificationException
,因为它实际上与并发无关(当迭代器尝试继续进行但列表在迭代器创建后已被修改时抛出异常)。 - Gerald MückeCopyOnWriteArrayList
对我的情况更好(因为我在UI线程上访问该字段)。 - NikolaiaddAll
方法。 - Fildor