哪些Java集合是同步的(线程安全的),哪些不是?
哪些Java集合是同步的,哪些不是哪些Java集合是同步的(线程安全的),哪些不是?,java,collections,Java,Collections,哪些Java集合是同步的,哪些不是 示例:哈希集未同步您可以使用 Collections.synchronizedCollection(Collection<T> c) Collections.synchronizedCollection(集合c) []我猜集合API的每个实现都是在文档中编写的。简单回答:没有一个集合的实现是同步的,因为synchronized不是类属性,它只适用于方法和块 我猜,您想知道哪些实现是线程安全的,java集合框架中的哪些类可以在多线程环境中安全使用
示例:哈希集未同步您可以使用
Collections.synchronizedCollection(Collection<T> c)
Collections.synchronizedCollection(集合c)
[]我猜集合API的每个实现都是在文档中编写的。简单回答:没有一个
集合的实现是同步的,因为synchronized
不是类属性,它只适用于方法和块
我猜,您想知道哪些实现是线程安全的,java集合框架中的哪些类可以在多线程环境中安全使用
这些信息总是包含在javadoc中(-它不是线程安全的)有三组集合
- Java 1.0集合主要是遗留类。这包括哈希表、向量、堆栈。这些是同步的,但我不建议您使用它们。属性可能是一个例外,但我不会在多线程上下文中使用它
- 1998年添加的Java 1.2集合在很大程度上取代了这些集合,这些集合不同步,但可以使用
collections.synchronizedXxx()
方法进行同步
- 2004年添加的Java 5.0并发集合支持无锁、线程安全的集合
简而言之,我建议您使用的所有集合都没有同步。集合界面中的ArrayList、LinkedList、HashSet、LinkedHashset和TreeSet以及HashMap、LinkedHashMap和Treemap都是非同步的
采集界面中的向量已同步同步会降低性能。当然,Java集合是不同步的。但是Java提供了一个同步包装器来同步Java集合
例如:
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.Iterator;
导入java.util.List;
公共类SynchronizedListExample{
公共静态void main(字符串[]args){
List syncList=Collections.synchronizedList(新的ArrayList());
syncList.add(“一”);//此处无需同步
添加(“两个”);
添加(“三”);
String st=syncList.get(0);//这里没有问题=>不需要同步
//在对同步列表进行迭代时,我们需要同步对同步列表的访问
//因为如果您不在这里同步,synchList可能会在迭代过程中更改
已同步(同步列表){
迭代器迭代器=syncList.Iterator();
while(iterator.hasNext()){
System.out.println(“项:“+iterator.next());
}
}
}
}
前面的示例完全错误
首先,您没有从不同的线程访问刚刚同步的列表,您无法证明同步正在正确执行,您无法证明添加进程是原子的。其次,列表上的synchronized子句本身是一种不好的做法,您不知道优化器是否会使用列表中的某个项来执行同步,从而导致意外行为。此外,同步的是对列表中元素的读/写访问,而不是列表本身。取出Collections.synchronized并查看输出。尝试很多次。
请举以下例子:
class ProcessSomething {
private List<Integer> integerList = Collections.synchronizedList(new ArrayList<>());
private void calculate() {
for (int i = 0; i < 10000; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
integerList.add(new Random().nextInt(100));
}
}
private void calculate2() {
for (int i = 0; i < 10000; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
integerList.add(new Random().nextInt(100));
}
}
public void process() {
Long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
calculate();
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
calculate2();
}
});
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException ex) {
Logger.getLogger(ProcessSomething.class.getName()).log(Level.SEVERE, null, ex);
}
Long end = System.currentTimeMillis();
System.out.println("Duration: " + (end - start));
System.out.println("List size: " + integerList.size());
}
}
public class App {
public static void main(String[] args) {
new ProcessSomething().process();
}
}
类处理某些东西{
private List integerList=Collections.synchronizedList(new ArrayList());
私有无效计算(){
对于(int i=0;i<10000;i++){
试一试{
睡眠(1);
}捕获(中断异常例外){
Logger.getLogger(App.class.getName()).log(Level.SEVERE,null,ex);
}
add(new Random().nextInt(100));
}
}
私有void calculate2(){
对于(int i=0;i<10000;i++){
试一试{
睡眠(1);
}捕获(中断异常例外){
Logger.getLogger(App.class.getName()).log(Level.SEVERE,null,ex);
}
add(new Random().nextInt(100));
}
}
公共程序(){
长启动=System.currentTimeMillis();
线程t1=新线程(新的可运行线程(){
公开募捐{
计算();
}
});
t1.start();
线程t2=新线程(新可运行(){
公开募捐{
计算2();
}
});
t2.start();
试一试{
t1.join();
t2.连接();
}捕获(中断异常例外){
Logger.getLogger(ProcessSomething.class.getName()).log(Level.SEVERE,null,ex);
}
Long end=System.currentTimeMillis();
System.out.println(“持续时间:”+(结束-开始));
System.out.println(“列表大小:+integerList.size());
}
}
公共类应用程序{
公共静态void main(字符串[]args){
新的ProcessSomething().process();
}
}
java.util包中的所有集合类(Vector和Hashtable除外)都不是线程安全的仅有的两个传统集合是线程安全的:Vector和Hashtable。为什么?
原因如下:同步可能非常昂贵!
您知道,Vector和Hashtable是Java历史早期存在的两个集合,它们从一开始就是为线程安全而设计的(如果您有机会查看它们的源代码,您将看到它们的方法都是同步的!)。但是,它们很快就会暴露出多线程程序中的低性能。您可能知道,同步需要锁,而锁总是需要时间来监视,这会降低性能。
Tha
class ProcessSomething {
private List<Integer> integerList = Collections.synchronizedList(new ArrayList<>());
private void calculate() {
for (int i = 0; i < 10000; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
integerList.add(new Random().nextInt(100));
}
}
private void calculate2() {
for (int i = 0; i < 10000; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
integerList.add(new Random().nextInt(100));
}
}
public void process() {
Long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
calculate();
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
calculate2();
}
});
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException ex) {
Logger.getLogger(ProcessSomething.class.getName()).log(Level.SEVERE, null, ex);
}
Long end = System.currentTimeMillis();
System.out.println("Duration: " + (end - start));
System.out.println("List size: " + integerList.size());
}
}
public class App {
public static void main(String[] args) {
new ProcessSomething().process();
}
}
List<String> syncList = Collections.synchronizedList(new ArrayList<String>());