Ans*_*hul 0 java multithreading
为什么以下代码只输出3 Thread-0时输出6行Thread-1?
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
为什么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++) {
Run Code Online (Sandbox Code Playgroud)
由于names在线程之间共享,因此您将修改两个线程中的列表.第一个线程添加3个名称,必须在第二个线程运行之前完成.然后第二个增加另一个3并吐出6.
如果你想要2个线程更新同一个列表,你应该通过使用并发集合或我在synchronized (names) {块内部进行添加来保护它.您的代码正在运行,因为它System.out.print()是一个同步类,因此它会导致在线程之间更新内存.如果您删除了这些print()调用,则每个线程names在运行时很可能会看到为空.它们也可能导致List损坏或其他不良.
至于为什么Thread-1吐出3 之前 Thread-0,线程是同时启动的,并且它是一个竞争条件,看看哪个先行.