91名师指路-头部
91名师指路

ArrayList 线程不安全的演示和解决方案

由于某些原因,现在不支持支付宝支付,如需要购买源码请加博主微信进行购买,微信号:13248254750

概述:arrayList 线程不安全,默认长度为10


带着如下疑问我们来各个击破。
(1)arrayList为什么是线程不安全的。
(2)如何证明arrayList是线程不安全的。
(3)arrayList既然线程不安全,如何解决。

一:arrayList为什么是线程不安全的。
答:因为看源码得知,arrayList的add方法没有加synchronized



二:如何证明arrayList是线程不安全的

代码如下:
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,此时可以证明是线程不安全的。


三:arrayList既然线程不安全,如何解决

(1)将arrayList改为Vector。

(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     阅读(673)

名师出品,必属精品    https://www.91mszl.com

联系博主    
用户登录遮罩层
x

账号登录

91名师指路-底部