在这种情况下我是否需要同步?

时间:2014-03-30 17:54:59

标签: java android multithreading listview

我正在制作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中的线程更多的线程。 谢谢你的帮助。

3 个答案:

答案 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,所以无论发生什么,用户多么疯狂/快速,事件都是串行处理的(由主线程处理)。

同步不会产生任何影响。