有两个线程,一个线程让列表添加十次,B线程将在list.size()>时退出5.我认为结果应该是" B在A加5后退出,可能是6,7,7,8,9"但结果是B永不退出。 另一个问题是当我在那里添加一条线时,它会没问题!为什么呢?
package com.lock;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Create by @author Henry on 2018/5/4
*/
public class NoWait {
static volatile ArrayList list = new ArrayList();
public static void main(String[] args) throws InterruptedException {
ThreadA a = new ThreadA(list);
a.setName("A");
a.start();
ThreadB b = new ThreadB(list);
b.setName("B");
b.start();
Thread.sleep(10000);
System.out.println("A is " + a.isAlive());
System.out.println("B is " + b.isAlive());
}
}
class ThreadA extends Thread{
private ArrayList list;
public ThreadA(ArrayList list){
this.list = list;
}
@Override
public void run(){
try{
for (int i = 0; i < 10; i++) {
list.add(i);
System.out.println("=====================================add "+(i+1));
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("A finished");
}
}
class ThreadB extends Thread{
String s = "";
private ArrayList list;
public ThreadB(ArrayList list){
this.list = list;
}
@Override
public void run(){
try{
while(true){
//s += list.size();
//System.out.println(list.size());
if(list.size() > 5){
System.out.println(">5 now, B gonne quit");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果是B Thread永不停止!这是我的第一个问题。
第二个是,当我添加这一行
//s += list.size();
//System.out.println(list.size());
没关系,为什么?!!它们是如何工作的!
答案 0 :(得分:2)
不保证线程B会看到线程A的任何更改,因为它们之间没有同步。
Volatile不会在这里做任何事情,因为它只能确保列表的引用对两个线程都可见,但不能更新其内容。
println具有内部同步功能,可以使线程之间的更改可见。