摘要:眾所周知這兩個結(jié)構(gòu)都不是線程安全的對于可以通過多個線程向其添加元素若它不是線程安全的則最后它實(shí)際存儲的元素數(shù)量很可能不等于實(shí)際添加的元素數(shù)量的驗(yàn)證方法也類似需要注意的是這里的線程不安全指的是原子操作比如這種得不到預(yù)期效果而不是和這樣一組操作
眾所周知, 這兩個結(jié)構(gòu)都不是線程安全的.對于ArrayList, 可以通過多個線程向其添加元素, 若它不是線程安全的, 則最后它實(shí)際存儲的元素數(shù)量很可能不等于實(shí)際添加的元素數(shù)量.HashMap的驗(yàn)證方法也類似
需要注意的是, 這里的線程不安全指的是原子操作, 比如add這種, 得不到預(yù)期效果, 而不是add和get這樣一組操作. 在原子操作線程安全的情況下, 一組原子操作也是線程不安全的, 需要另外加鎖.
證明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 HashMapfirstHashMap = 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))); } } } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/65127.html
摘要:同步包裝器任何集合類使用同步包裝器都會變成線程安全的,會將集合的方法使用鎖加以保護(hù),保證線程的安全訪問。線程池中的線程執(zhí)行完畢并不會馬上死亡,而是在池中準(zhǔn)備為下一個請求提供服務(wù)。 多線程并發(fā)修改一個數(shù)據(jù)結(jié)構(gòu),很容易破壞這個數(shù)據(jù)結(jié)構(gòu),如散列表。鎖能夠保護(hù)共享數(shù)據(jù)結(jié)構(gòu),但選擇線程安全的實(shí)現(xiàn)更好更容易,如阻塞隊列就是線程安全的集合。 線程安全的集合 Vector和HashTable類提供了線...
摘要:加載因子是哈希表在其容量自動增加之前可以達(dá)到多滿的一種尺度。當(dāng)哈希表中的條目數(shù)超出了加載因子與當(dāng)前容量的乘積時,則要對該哈希表進(jìn)行操作即重建內(nèi)部數(shù)據(jù)結(jié)構(gòu),從而哈希表將具有大約兩倍的桶數(shù)。 showImg(https://upload-images.jianshu.io/upload_images/4565148-98b22ba5ae7d9723.jpg?imageMogr2/auto-...
摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時有了較大的變化,當(dāng)鏈表長度大于閾值默認(rèn)為時,將鏈表轉(zhuǎn)化為紅黑樹,以減少搜索時間。有序,唯一紅黑樹自平衡的排序二叉樹。 本文是最最最常見Java面試題總結(jié)系列第三周的文章。主要內(nèi)容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底層...
摘要:概述集合類主要有大分支,及。不能保證元素的排列順序,順序有可能發(fā)生變化不是同步的集合元素可以是但只能放入一個是接口的唯一實(shí)現(xiàn)類,可以確保集合元素處于排序狀態(tài)。如果這兩個的通過比較返回,新添加的將覆蓋集合中原有的,但不會覆蓋。 概述 Java集合類主要有2大分支,Collection及Map。Collection體系如下: https://upload-images.jianshu......
閱讀 1403·2021-09-27 13:56
閱讀 2446·2019-08-26 10:35
閱讀 3593·2019-08-23 15:53
閱讀 1945·2019-08-23 14:42
閱讀 1311·2019-08-23 14:33
閱讀 3659·2019-08-23 12:36
閱讀 2057·2019-08-22 18:46
閱讀 1082·2019-08-22 14:06