public class test14 {
private static List<Integer> arraylist=Collections.synchronizedList(new ArrayList<Integer>());
// private static List<Integer> arraylist=new ArrayList<>();
public static void main(String[] args) {
for(int i=0;i<2000;i++)
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(!Thread.interrupted()&&arraylist.size()<10000){
arraylist.add(0);
}
}
}).start();
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("size: "+arraylist.size());
}
}
输出:size: 10011网上有个例子证明ArrayList是非线程安全的:
http://m.blog.csdn.net/article/details?id=52163131 ,
大部分的资料只是说ArrayList是非线程安全的,如果要使其线程安全,可以使用Collections.synchronizedList()对其进行包装,那么我模仿例子自己写了一段代码想验证一下,可是得到的输出却不是size==10000
既然包装以后是线程安全的容器,为什么会出现这样的情况呢?我也翻看了Collections.synchronizedList()的相关源码,发现size()和add()都是有同步的,这让我更加不解了
private static List<Integer> arraylist=Collections.synchronizedList(new ArrayList<Integer>());
// private static List<Integer> arraylist=new ArrayList<>();
public static void main(String[] args) {
for(int i=0;i<2000;i++)
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(!Thread.interrupted()&&arraylist.size()<10000){
arraylist.add(0);
}
}
}).start();
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("size: "+arraylist.size());
}
}
输出:size: 10011网上有个例子证明ArrayList是非线程安全的:
http://m.blog.csdn.net/article/details?id=52163131 ,
大部分的资料只是说ArrayList是非线程安全的,如果要使其线程安全,可以使用Collections.synchronizedList()对其进行包装,那么我模仿例子自己写了一段代码想验证一下,可是得到的输出却不是size==10000
既然包装以后是线程安全的容器,为什么会出现这样的情况呢?我也翻看了Collections.synchronizedList()的相关源码,发现size()和add()都是有同步的,这让我更加不解了
arraylist.add(0);
}
哦,有些明白了,那是不是说,即使我们使用JDK里面线程安全的容器,如果要套用自己的其他方法的时候,代码也不能随便写,也要考虑同步问题?仿照书上写成double check形式,测试好像没问题,但我不确定是否正确,而且这样写,直接用普通的ArrayList也能得到size=10000, 不过特别的慢,这又是为什么呢public static void main(String[] args) {
for(int i=0;i<2000;i++)
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(!Thread.interrupted()){
if(arraylist.size()<10000)
synchronized(arraylist){
if(arraylist.size()<10000)
arraylist.add(0);
}
}
}
}).start();
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("size: "+arraylist.size());
}
即使我们使用JDK里面线程安全的容器,如果要套用自己的其他方法的时候,代码也不能随便写,也要考虑同步问题?