再次提出有关ArrayList和同步的问题。ArrayList,线程和同步 - 如何准确同步多个线程
我只是想知道这是什么片断究竟:
ArrayList<ObjectX> list = ....;
synchronized (list) {
if (list.contains(objectxy) == false) {
list.add(objectxy);
}
}
Ive得到了充满ObjectXs一个ArrayList中。我想添加一个元素到列表中,但只有当列表不包含相同的元素。我之前(在另一种方法中)检查列表是否包含对象 - 结果是否定的。但是有可能两个线程同时认为结果是否定的,并且他们都尝试添加objectxy。 (还有其他一些必须在中间做的事情,这就是为什么我不能同步整个过程)
所以,在过程之后,当现在的线程来到上面的片段,我想防止这两个都添加该对象到列表中。所以我想当我同步访问列表时,只有一个线程可以检查它是否包含对象,然后添加它。在它之后,第二个线程可以访问列表,查看该对象已经在其中并且不再添加它。
那就是我想要达到的。 它会工作吗? :-)
所以,如果是的话,我想知道片段到底是什么。是否阻止两个线程同时访问此确切的代码?这样代码只能同时用于一个线程?
或者它锁定列表本身整个时间,在应用程序的任何线程是谁在这个时候尝试访问列表 - 随时随地? (我没有其他的add()在我的代码中,但许多gets(),这就是为什么Id喜欢知道其他线程是否可以访问列表,并仍然获取元素,而另一个线程访问上面的代码)。
ArrayList本身是一个使用应用程序与主体连接的成员变量。多个不同的线程同时访问上面的代码是正确的如果它们不是从相同的主体发送的,那么正确的?
所以,这就是Id想知道的。我试图标记我的问题,以便更容易地回答它们。感谢您的帮助! :-)
[编辑]谢谢你所有的答案,这几乎所有的说法都一样!我认为现在很清楚! :-)
- 同步代码块只能由其中一个主体线程访问。 (其他校长的线索与特殊校长无关)。该列表本身可以随时从其他线程访问 - 只要对它的访问不与同步块同步即可。如果是这样,线程必须等待,直到它可以访问列表(这意味着没有其他线程同时在同步块中)
是否正确?我希望如此:-)
感谢您的回答。我不使用synchronizedList,因为我对它有非常少的操作需要同步 - 这就是为什么我认为这是没有必要的。由于CopyOnWriteArrayList也是线程安全的,我认为这对我的应用程序来说也太多了 - 我实际上并不需要在每个点都进行同步。 :-) – nano7 2011-05-27 10:16:56
这种方法要非常小心:您必须确保*每个*列表访问都不会与任何其他访问重叠。例如,如果有一个线程执行get()而另一个执行同步(list){add()/ set()}指令的机会,您必须*同步get()指令。 – Flavio 2011-05-27 10:27:18
为什么?如果仅仅因为用户可以获得不是最新的数据(可能缺少一个添加),那么这并不重要 - 至少不适用于我的应用程序,我的意思是:-)我可以接受那个 – nano7 2011-05-27 12:01:38