持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
1 线程安全的集合
-
Vector
为什么
Vecter是线程安全的呢?查看源代码:从上面的代码可以看到,每个方法都加上了
synchronized关键字,所以它是线程安全的。但是因为它的所有方式都加上了synchronized关键字,那么无论你是否需要对其进行多线程访问时,它都会对其进行锁定,执行效率会很低。现在已经弃用。 -
HashTable
HashTable和Vector类似,都是在每个方法上加上synchronized关键字来达到线程安全的目的。我们可以从下面的源代码可以看出:
2 java.util.concurrent下的线程安全集合
java.util包下有一个concurrent包,下面的集合都是线程安全的集合,当需要使用线程来操作集合时,就调用该包下面的集合。下面看一段线程不安全的集合代码:
import java.util.LinkedList;
import java.util.List;
public class ThreadSafe {
public static void main(String[] args) throws InterruptedException {
List<String> list = new LinkedList<>();
Thread thread1 =new Thread(()->{
for (int i = 0; i < 1000; i++) {
list.add("add");
}
});
Thread thread2 = new Thread(()->{
for (int i = 0; i < 1000; i++) {
list.add("add");
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(list.size());
}
}
运行结果:
线程安全的集合:
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ThreadSafe {
public static void main(String[] args) throws InterruptedException {
List<String> list = new CopyOnWriteArrayList<>();
Thread thread1 =new Thread(()->{
for (int i = 0; i < 1000; i++) {
list.add("add");
}
});
Thread thread2 = new Thread(()->{
for (int i = 0; i < 1000; i++) {
list.add("add");
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(list.size());
}
}
运行结果:
3 使用Collections包装成线程安全
-
包装列表list
List<String> list = Collections.synchronizedList(new ArrayList<>()); -
包装集合set
Set<String> set = Collections.synchronizedSet(new HashSet<>()); -
包装字典map
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());