我正在制作Android应用程序。我有一个课程,我每隔30秒从数据库得到一些订单,如下:
public class OrderScheduler {
private List<OrderMain> orders = Collections.synchronizedList(
new ArrayList<OrderMain>());
...
private void main() {
service.scheduleAtFixedRate(new Runnable() {
public void run() {
orders = getStuff();
}
}, 0, 30, TimeUnit.SECONDS);
}
}
然后有一个Activity类,我使用上面列表中的对象创建ListView,如下所示:
newOrdersListView = (ListView) findViewById(R.id.newOrdersListView);
OrderScheduler os = OrderScheduler.getInstance();
List<OrderMain> newOrders = (os.getOrders() == null) ?
new ArrayList<OrderMain>() : os.getOrders();
ArrayAdapter<OrderMain> listAdapter = new ArrayAdapter<OrderMain>(
this, R.layout.listview_row, newOrders);
newOrdersListView.setAdapter(listAdapter);
我在javadoc中读取迭代同步列表时我需要同步它。
我的问题是,当我点击此列表视图的某个项目时,onItemClick方法是否需要处于同步块中?我认为当我从listview中选择一些项目时,它基本上需要迭代newOrders列表。
顺便说一句,我现在不同步这个监听器方法,它似乎有效。我不会在此应用程序中创建比OrderScheduler中的线程更多的线程。 谢谢你的帮助。
答案 0 :(得分:2)
看起来你的.getStuff()
方法每次产生一个完全不同的列表;看起来它的结果只有一个消费者。此外,看起来消费者不会修改结果。
因此,我的建议是使用AtomicReference
。
您的&#34;制作人&#34;然后代码会这样做:
ref.set(getStuff());
和您的&#34;消费者&#34;:
List<OrderMain> newOrders = ref.get();
您的ref
将是生产者和消费者之间共享的AtomicReference<List<OrderMain>>
。
答案 1 :(得分:0)
使用当前代码,您不需要同步任何内容,因为您每次都创建ArrayList
(如果您使用迭代器,因为在内部它将使用旧的ArrayList)。
您在迭代时需要同步列表的原因是因为您可以获得ConcurrentModificationException
(迭代器不允许您在阅读时对列表进行任何更改)
PS我认为getStuff
创建了一个新的ArrayList
,因为你做了orders = getStuff();
,如果你改变代码来修改你的ArrayList,你会看到ConcurrentModificationException
异常。
答案 2 :(得分:0)
问问自己是谁在执行onItemClick。
它的主要(UI)thead,所以无论发生什么,用户多么疯狂/快速,事件都是串行处理的(由主线程处理)。
同步不会产生任何影响。