原 ArrayList 线程不安全的演示和解决方案
版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
本文链接:https://www.91mszl.com/zhangwuji/article/details/1130
package com.mszl.thread;
import java.util.ArrayList;
import java.util.List;
/**
* 功能:证明ArrayList线程不安全
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ArrayListDemo {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
for(int i=1; i<=3; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
String uuid="123";
list.add(uuid);
System.out.println(list);
}
});
t.start();
}
}
}
执行结果:
[123]
[123, 123]
[123, 123, 123]
备注:我们同时开启三个线程,来循环的往list里面添加数据,多次执行会发现报错:Exception in thread "Thread-0" java.util.ConcurrentModificationException,此时可以证明是线程不安全的。
(2)采用辅助工具类在外面包装一层。Collections.synchronizedList(new ArrayList<String>())
(3)写时复制。CopyOnWriteArrayList
(1)将arrayList改为Vector 代码如下:
我们先来看Verctor的add方法,源码如下:
加上了synchronized 所以它可以保证线程安全。
改为Vector后的代码如下:
package com.mszl.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
/**
* 功能:证明ArrayList线程不安全
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ArrayListDemo {
public static void main(String[] args) {
List<String> list=new Vector<String>();
for(int i=1; i<=10; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
String uuid="123";
list.add(uuid);
System.out.println(list);
}
});
t.start();
}
}
}
执行结果:
[123]
[123, 123, 123]
[123, 123]
[123, 123, 123, 123]
[123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123, 123, 123, 123]
(2)采用辅助工具类在外面包装一层。
代码如下:
package com.mszl.thread;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
/**
* 功能:证明ArrayList线程不安全
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ArrayListDemo {
public static void main(String[] args) {
List<String> list=Collections.synchronizedList(new ArrayList<String>());
for(int i=1; i<=10; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
String uuid="123";
list.add(uuid);
System.out.println(list);
}
});
t.start();
}
}
}
执行结果:
[123]
[123, 123, 123, 123]
[123, 123, 123]
[123, 123]
[123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123, 123, 123]
[123, 123, 123, 123, 123, 123, 123, 123, 123, 123]
三:写时复制。CopyOnWriteArrayList
代码如下:
package com.mszl.thread;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 功能:证明ArrayList线程不安全
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ArrayListDemo {
public static void main(String[] args) {
List<String> list=new CopyOnWriteArrayList<String>();
for(int i=1; i<=10; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
String uuid=UUID.randomUUID().toString().substring(0, 8); // "123";
list.add(uuid);
System.out.println(list);
}
});
t.start();
}
}
}
执行结果:
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968, 0c572e7a]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968, 0c572e7a]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968, 0c572e7a]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968]
[89a7cfe6, 69e12827, cef486b7, b52962bf, a0debce2, f1c51d6c, a38b6354, 20964a0e, 60e31968, 0c572e7a]
以下是CopyOnWriteArrayList的add方法的源码。采用了ReentrantLock
2019-11-26 11:14:34 阅读(838)
名师出品,必属精品 https://www.91mszl.com
博主信息