温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

hashmap是线程安全吗

发布时间:2021-12-30 09:15:25 来源:亿速云 阅读:142 作者:iii 栏目:大数据

本篇内容主要讲解“hashmap是线程安全吗”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“hashmap是线程安全吗”吧!

目前普遍都是使用jdk1.8 了。 其实要模拟jdk1.8的多线程不安全出来,其实很简单的。

复制一份hashmap的代码出来。接着 将 hashmap的容量固定为1 ,并且禁止扩容。

比如: 修改 resize代码。 第一次可以扩展,容量是1。第二次就不可以了。

  final Node<K,V>[] resize() {         if (FirstResize.get() !=0){             System.out.println(">>>>不可以扩展>>>");             return  table;         }else{             FirstResize.addAndGet(1);         }

put 方法里面,进行控制线程的调度,就可以模拟了

 /**      * Implements Map.put and related methods      *      * @param hash hash for key      * @param key the key      * @param value the value to put      * @param onlyIfAbsent if true, don't change existing value      * @param evict if false, the table is in creation mode.      * @return previous value, or null if none      */     final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                    boolean evict) {         Node<K,V>[] tab; Node<K,V> p; int n, i;         if ((tab = table) == null || (n = tab.length) == 0)             n = (tab = resize()).length;         if ((p = tab[i = (n - 1) & hash]) == null){ // 多线程并发,会发生 数据覆盖             if (Thread.currentThread().getName().equals("a")){                 System.out.println("线程A休眠,暂停执行"); //模拟, 让其覆盖 其他线程 的值                 try {                     Thread.sleep(5*1000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }             System.out.println("i >>>>"+i);             System.out.println("插入:"+key +": "+value);             tab[i] = newNode(hash, key, value, null);         }         else {             Node<K,V> e; K k;             if (p.hash == hash &&                     ((k = p.key) == key || (key != null && key.equals(k))))                 e = p;             else if (p instanceof TreeNode)                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);             else {                 for (int binCount = 0; ; ++binCount) {                     if ((e = p.next) == null) {                         //同理也会 发生并发 put的时候被覆盖的情况                         p.next = newNode(hash, key, value, null);                         if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                             treeifyBin(tab, hash);                         break;                     }                     if (e.hash == hash &&                             ((k = e.key) == key || (key != null && key.equals(k))))                         break;                     p = e;                 }             }             if (e != null) { // existing mapping for key                 V oldValue = e.value;                 if (!onlyIfAbsent || oldValue == null)                     e.value = value;                 afterNodeAccess(e);                 return oldValue;             }         }         ++modCount;         if (++size > threshold)             resize();         afterNodeInsertion(evict);         return null;     }

测试代码:

package com.interview.javabasic.myhashmap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; public class TestThreadMap {               private static HashMap<Integer,Integer> mh=new HashMap(1);     public static void main(String[] args) {         HashMapThread thread0 = new HashMapThread("a",mh);         HashMapThread thread1 = new HashMapThread("b",mh);         thread0.start();         thread1.start();         try {             Thread.sleep(15*1000);         } catch (InterruptedException e) {             e.printStackTrace();         }         // 此时会发现 map 里面  只有 2,2   。         //  mh.put(3,3); 被覆盖了         System.out.println(mh);     } } class HashMapThread extends Thread {     HashMap<Integer,Integer> mh;     private  String namet;     public HashMapThread(String name, HashMap mh) {         super(name);         this.namet=name;         this.mh=mh;     }     @Override     public void run() {         if (namet.equals("b")){             try {                 Thread.sleep(2*1000);             } catch (InterruptedException e) {                 e.printStackTrace();             }             mh.put(3,3);         }else{             mh.put(2,2);         }     } }

到此,相信大家对“hashmap是线程安全吗”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI