Collections.synchronizedList()方法有什么用?它似乎没有同步列表 [英] What is the use of Collections.synchronizedList() method? It doesn't seem to synchronize the list
问题描述
我正在尝试使用两个线程将 String
值添加到 ArrayList
。我想要的是,当一个线程添加值时,另一个线程不应该干扰,所以我使用了 Collections.synchronizedList
方法。但似乎如果我没有在对象上显式同步,则以不同步的方式完成添加。
I am trying to add String
values to an ArrayList
using two threads. What I want is that while one thread is adding the values the other thread should not interfere so I have used the Collections.synchronizedList
method. But it appears that if I don't explicitly synchronize on an object the adding is done in an unsynchronized way.
没有显式同步块:
public class SynTest {
public static void main(String []args){
final List<String> list=new ArrayList<String>();
final List<String> synList=Collections.synchronizedList(list);
final Object o=new Object();
Thread tOne=new Thread(new Runnable(){
@Override
public void run() {
//synchronized(o){
for(int i=0;i<100;i++){
System.out.println(synList.add("add one"+i)+ " one");
}
//}
}
});
Thread tTwo=new Thread(new Runnable(){
@Override
public void run() {
//synchronized(o){
for(int i=0;i<100;i++){
System.out.println(synList.add("add two"+i)+" two");
}
//}
}
});
tOne.start();
tTwo.start();
}
}
我得到的输出是:
true one
true two
true one
true two
true one
true two
true two
true one
true one
true one...
显式同步块取消注释我在添加时停止来自其他线程的干扰。一旦线程获得了锁,它就会执行直到它完成。
With the explicit synchronized block uncommented I'm stopping the interference from the other thread while adding. Once the thread has acquired the lock it is executing until it is finished.
取消注释同步块后的示例输出:
sample output after uncommenting the synchronized block:
true one
true one
true one
true one
true one
true one
true one
true one...
那么为什么 Collections.synchronizedList()
没有进行同步?
So why is the Collections.synchronizedList()
not doing the synchronization?
推荐答案
同步列表仅同步此列表的方法。
A synchronized list only synchronizes methods of this list.
这意味着当另一个线程当前正在运行此列表中的方法时,线程将无法修改列表。处理方法时对象被锁定。
It means a thread won't be able to modify the list while another thread is currently running a method from this list. The object is locked while processing method.
例如,假设两个线程在列表中运行 addAll
,有2个不同的列表( A = A1,A2,A3
, B = B1,B2,B3
)作为参数。
As an example, Let's say two threads run addAll
on your list, with 2 different lists (A=A1,A2,A3
, B=B1,B2,B3
) as parameter.
-
由于方法已同步,您可以确定这些列表不会像
一样随机合并A1,B1,A2,A3,B2,B3
您没有决定某个线程何时将该流程移交给另一个线程,所以你可以得到 A1,A2,A3,B1,B2,B3
或 B1,B2,B3,A1,A2,A3
。
You don't decide when a thread handover the process to the other thread so you can either get A1,A2,A3,B1,B2,B3
or B1,B2,B3,A1,A2,A3
.
在第一段代码中,两个线程同时运行。并且都尝试将添加
元素添加到列表中。除了 add
方法上的同步之外,你没有办法阻止一个线程,所以没有什么能阻止线程1运行多个 add
在将流程移交给线程2之前的操作。所以你的输出是完全正常的。
In your first piece of code, both threads runs on the same time. And both try to add
an element to the list. You don't have any way to block one thread except the synchronization on the add
method so nothing prevent thread 1 from running multiple add
operation before handing over the process to thread 2. So your output is perfectly normal.
在你的第二段代码(未注释的代码)中,你明确指出一个线程在开始循环之前从另一个线程完全锁定列表。因此,您可以确保您的某个线程在另一个线程可以访问列表之前运行完整循环。
In your second piece of code (the uncommented one), you clearly state that a thread completely lock the list from the other thread before starting the loop. Hence, you make sure one of your thread will run the full loop before the other one could access the list.
这篇关于Collections.synchronizedList()方法有什么用?它似乎没有同步列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!