ArrayList 是线程不安全的,通过一段代码来体现.
class Test3 implements Runnable{
ArrayList<String> arrayList;
Test3(ArrayList<String> arrayList){
this.arrayList=arrayList;
}
@Override
public void run() {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
arrayList.add(Thread.currentThread().getName());
}
}
public class JoinTest{
public static void main(String[] args) throws InterruptedException {
ArrayList<String> list=new ArrayList<>();
Test3 test3=new Test3(list);
for(int i=0; i<50; i++){
new Thread(test3,""+i).start();
}
Thread.sleep(3000);
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i));
}
}
}
这段代码创建了50个线程,每个线程共享一个线程体.
在打印结果中发现会有null的情况,说明该程序并没有往list中添加50个,说明ArrayList的操作不能保证其原子性,是不安全的.
解决方法
1,使用synchronized
这样synchronized里的代码会成为一个原子.
@Override
public void run() {
synchronized (this){
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
arrayList.add(Thread.currentThread().getName());
}
}
2,使用Vector
Vector的所有方法都是同步的,但是这也代表着其开销较大,因此在单线程操作时可以用ArrayList替代.