资讯专栏INFORMATION COLUMN

java证明ArrayList和HashMap的非线程安全性

_Suqin / 2316人阅读

摘要:众所周知这两个结构都不是线程安全的对于可以通过多个线程向其添加元素若它不是线程安全的则最后它实际存储的元素数量很可能不等于实际添加的元素数量的验证方法也类似需要注意的是这里的线程不安全指的是原子操作比如这种得不到预期效果而不是和这样一组操作

众所周知, 这两个结构都不是线程安全的.对于ArrayList, 可以通过多个线程向其添加元素, 若它不是线程安全的, 则最后它实际存储的元素数量很可能不等于实际添加的元素数量.HashMap的验证方法也类似

需要注意的是, 这里的线程不安全指的是原子操作, 比如add这种, 得不到预期效果, 而不是addget这样一组操作. 在原子操作线程安全的情况下, 一组原子操作也是线程不安全的, 需要另外加锁.

证明ArrayList的非线程安全性

package com.ibm.javacore.collections.threadsafe;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class ThreadSafeDemo {
    public static int demo(final List list, final int testCount) throws InterruptedException {
        ThreadGroup group = new ThreadGroup(list.getClass().getName() + "@" + list.hashCode()); 
        final Random rand = new Random(); 
        
        Runnable listAppender = new Runnable() {
            public void run() {
                try {
                    Thread.sleep(rand.nextInt(2));
                } catch (InterruptedException e) {
                    return; 
                } 
                list.add("0"); 
            }
        }; 
        
        for (int i = 0; i < testCount; i++) {
            new Thread(group, listAppender, "InsertList-" + i).start(); 
        }
        
        while (group.activeCount() > 0) {
            Thread.sleep(10); 
        }
        
        return list.size(); 
    }
    public static void main(String[] args) throws InterruptedException {
        List unsafeList = new ArrayList(); 
        List safeList = Collections.synchronizedList(new ArrayList()); 
        final int N = 10000; 
        for (int i = 0; i < 10; i++) {
            unsafeList.clear(); 
            safeList.clear(); 
            int unsafeSize = demo(unsafeList, N); 
            int safeSize = demo(safeList, N); 
            System.out.println("unsafe/safe: " + unsafeSize + "/" + safeSize); 
        }
    }
}

证明HashMap的非线程安全性

package com.concurrence;

import java.util.HashMap;

public class ThreadNotSafeHashmap {
    public static void main(String args[]) throws InterruptedException {
        final HashMap firstHashMap = new HashMap();
        Thread t1 = new Thread() {
            public void run() {
                for (int i = 0; i < 2500; i++) {
                    firstHashMap.put(String.valueOf(i), String.valueOf(i));
                }
            }
        };
        Thread t2 = new Thread() {
            public void run() {
                for (int j = 2500; j < 5000; j++) {
                    firstHashMap.put(String.valueOf(j), String.valueOf(j));
                }
            }
        };
        t1.start();
        t2.start();

        Thread.sleep(1000);
        for (int k = 0; k < 5000; k++) {
            if (!String.valueOf(k).equals(firstHashMap.get(String.valueOf(k)))) {
                System.err.println(String.valueOf(k) + ":" + firstHashMap.get(String.valueOf(k)));
            }
        }
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65127.html

相关文章

  • Java线程线程安全与异步执行

    摘要:同步包装器任何集合类使用同步包装器都会变成线程安全的,会将集合的方法使用锁加以保护,保证线程的安全访问。线程池中的线程执行完毕并不会马上死亡,而是在池中准备为下一个请求提供服务。 多线程并发修改一个数据结构,很容易破坏这个数据结构,如散列表。锁能够保护共享数据结构,但选择线程安全的实现更好更容易,如阻塞队列就是线程安全的集合。 线程安全的集合 Vector和HashTable类提供了线...

    taoszu 评论0 收藏0
  • HashMap 你真的了解吗?

    摘要:加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行操作即重建内部数据结构,从而哈希表将具有大约两倍的桶数。 showImg(https://upload-images.jianshu.io/upload_images/4565148-98b22ba5ae7d9723.jpg?imageMogr2/auto-...

    RdouTyping 评论0 收藏0
  • 这几道Java集合框架面试题在面试中几乎必问

    摘要:若遇到哈希冲突,则将冲突的值加到链表中即可。之后相比于之前的版本,之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值默认为时,将链表转化为红黑树,以减少搜索时间。有序,唯一红黑树自平衡的排序二叉树。 本文是最最最常见Java面试题总结系列第三周的文章。主要内容: Arraylist 与 LinkedList 异同 ArrayList 与 Vector 区别 HashMap的底层...

    bigdevil_s 评论0 收藏0
  • 集合小记

    摘要:解決沖突开放定址法拉链法表解決沖突开放定址法再哈希法链地址法建立公共溢出区并发包中的线程安全的集合容器线程安全的,不允许为,默认个的数组,每个中实现就是了,通过定位。基于数组,线程安全的集合类,容量可以限制。 List   List 元素是有序的、可重复,实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。   ArrayList:动态数组...

    alaege 评论0 收藏0
  • Java集合总结

    摘要:概述集合类主要有大分支,及。不能保证元素的排列顺序,顺序有可能发生变化不是同步的集合元素可以是但只能放入一个是接口的唯一实现类,可以确保集合元素处于排序状态。如果这两个的通过比较返回,新添加的将覆盖集合中原有的,但不会覆盖。 概述 Java集合类主要有2大分支,Collection及Map。Collection体系如下: https://upload-images.jianshu......

    toddmark 评论0 收藏0

发表评论

0条评论

_Suqin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<