为什么当Thread-0
仅输出3时,以下代码会Thread-1
输出6行?
public class NameList{
private List names = new ArrayList();
public synchronized void addName(String name){
names.add(name);
}
public synchronized void print(){
for (int i = 0; i < names.size(); i++) {
System.out.print(names.get(i)+" ");
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String args[]){
final NameList nl = new NameList();
for (int i = 0; i <2; i++) {
new Thread(){
public void run(){
nl.addName("A");
nl.addName("B");
nl.addName("C");
nl.print();
}
}.start();
}
}
}
输出:
A Thread-1
B Thread-1
C Thread-1
A Thread-0
B Thread-0
C Thread-0
A Thread-0
B Thread-0
C Thread-0
答案 0 :(得分:6)
为什么Thread-0输出6次,thread-1 3 ?????
因为每个帖子都根据NameList.names
:
// the threads share the same `NameList`
final NameList nl = new NameList();
...
nl.addName("A");
...
for (int i = 0; i < names.size(); i++) {
由于线程之间共享names
,因此您正在修改两个线程中的列表。第一个线程添加3个名称,必须在第二个线程运行之前完成。然后第二个增加另一个3并吐出6。
如果你想要2个线程更新同一个列表,你应该通过使用并发集合或我在synchronized (names) {
块内部进行添加来保护它。您的代码正在运行,因为System.out.print()
是一个同步类,因此它会导致在线程之间更新内存。如果您删除了print()
次调用,则每个线程在运行时很可能会看到names
为空。它们也可能导致List
被破坏或其他不良。
至于为什么Thread-1
在 Thread-0
之前吐出3 ,所以线程会同时启动,这是一个竞争条件,看看哪一个先行。
答案 1 :(得分:0)
因为每个线程都在列表中添加3个名称,所以,在第二个线程运行之后,您添加了6个名称,并且两个线程中的一个将全部打印出来。