2013-10-17 49 views
2

我有一个由多个线程访问的ArrayList。主线程仅清除列表,其他人添加到列表中。我不希望列表被清除,而另一个线程正在向它添加项目。我希望列表在线程添加项目时锁定。Java列表同步

这是增加线程的代码:

synchronized (items) 
{ 
    int length = jsonArray.length(); 
    if ((length > 0)) for (int i = 0; i < length; i++) 
    { 
     items.add(new Item(jsonArray.getJSONObject(i))); 
    } 
} 

但我不使用synchronized块进行结算。清除同步块是否必要?

回答

1

我不希望列表被清除,而另一个线程正在添加项目。

那么是的,你需要有clear例程​​以及。

在下面的示例中,add中的同步语句不会阻止clear

public void add(T t) { 
    synchronized(items) { 
     items.add(t); 
    } 
} 

public void clear() { 
    items.clear(); 
} 
+0

那么,我得到的是synchronized块不完全锁定列表,它只锁定它在这种情况下从其他添加线程? – Ali

+0

如果某个线程在主线程执行清除操作时开始添加该怎么办? –

+0

'synchronized(items)'在这里阻止'items.add(t)'的多个simulatenous调用。由于缺乏“同步”,“清除”程序甚至不知道或关心锁。 –

2

一个快速的方法来处理,这是只使用

List<Foo> items = Collections.synchronizedList(new ArrayList<Foo>()); 

所有方法都将被同步,你会是安全的。

如果有人在这里评论有关性能的信息,请提供OP的场景的实际数据以备份您的声明。

+1

当我阅读有关synchronizedList时,它只保护一个添加,而不是一堆添加。 – Ali

+0

那么,你可以使用addAll()来添加一批物品。虽然你的情况有点不清楚。为什么主线程清除数组?它是否删除项目并将它们存储在其他地方? – Kayaman

+0

不,用户选择另一个订单时,我清除该列表,以便从互联网上加载新项目。如果其他线程在清除之后添加到它,则它们位于列表的顶部。 – Ali