我有一个函数: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
}
}
}
}
上的列表,然后继续清除并重新填充它?
如果没有,我应该怎么做?
答案 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();
一样。