原 hashSet 线程不安全的演示和解决方案
版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
本文链接:https://www.91mszl.com/zhangwuji/article/details/1131
一:如何证明hashset线程不安全。
代码如下:
package com.mszl.thread;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* 功能:证明HashSet线程不安全
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class HashSetDemo {
public static void main(String[] args) {
Set<String> st=new HashSet<String>();
for(int i=1; i<=50; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
st.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(Thread.currentThread().getName() + "\t" + st);
}
});
t.start();
}
}
}
执行结果:
Exception in thread "Thread-20" java.util.ConcurrentModificationException
由此证明了hashSet 线程不安全。
二:如何解决hashSet线程不安全。
(1)使用辅助类包装一层。Collections.synchronizedSet(new HashSet<String>())
(2)使用CopyOnWriteArraySet
(1)使用辅助类包装一层,代码如下
package com.mszl.thread;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* 功能:证明HashSet线程不安全和解决方案
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class HashSetDemo {
public static void main(String[] args) {
// Set<String> st=new HashSet<String>();
Set<String> st=Collections.synchronizedSet(new HashSet<String>());
for(int i=1; i<=50; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
st.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(Thread.currentThread().getName() + "\t" + st);
}
});
t.start();
}
}
}
(2)使用CopyOnWriteArraySet,代码如下。
package com.mszl.thread;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* 功能:证明HashSet线程不安全和解决方案
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class HashSetDemo {
public static void main(String[] args) {
// Set<String> st=new HashSet<String>();
// Set<String> st=Collections.synchronizedSet(new HashSet<String>());
Set<String> st=new CopyOnWriteArraySet<String>();
for(int i=1; i<=50; i++){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
st.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(Thread.currentThread().getName() + "\t" + st);
}
});
t.start();
}
}
}
三:hashSet 底层是hashMap,但是hashMap的add方法是添加k和v,为什么hashSet可以只添加k就可以了。
我们看hashSet的add方法源码,如下图所示。
可以知道value是一个Object PRESENT的固定值。所以我们不用去关心value是什么,只用管key。
2019-11-26 13:05:51 阅读(1135)
名师出品,必属精品 https://www.91mszl.com
博主信息