摘要:眾所周知這兩個結構都不是線程安全的對于可以通過多個線程向其添加元素若它不是線程安全的則最后它實際存儲的元素數量很可能不等于實際添加的元素數量的驗證方法也類似需要注意的是這里的線程不安全指的是原子操作比如這種得不到預期效果而不是和這樣一組操作
眾所周知, 這兩個結構都不是線程安全的.對于ArrayList, 可以通過多個線程向其添加元素, 若它不是線程安全的, 則最后它實際存儲的元素數量很可能不等于實際添加的元素數量.HashMap的驗證方法也類似
需要注意的是, 這里的線程不安全指的是原子操作, 比如add這種, 得不到預期效果, 而不是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))); } } } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65127.html
摘要:同步包裝器任何集合類使用同步包裝器都會變成線程安全的,會將集合的方法使用鎖加以保護,保證線程的安全訪問。線程池中的線程執行完畢并不會馬上死亡,而是在池中準備為下一個請求提供服務。 多線程并發修改一個數據結構,很容易破壞這個數據結構,如散列表。鎖能夠保護共享數據結構,但選擇線程安全的實現更好更容易,如阻塞隊列就是線程安全的集合。 線程安全的集合 Vector和HashTable類提供了線...
摘要:加載因子是哈希表在其容量自動增加之前可以達到多滿的一種尺度。當哈希表中的條目數超出了加載因子與當前容量的乘積時,則要對該哈希表進行操作即重建內部數據結構,從而哈希表將具有大約兩倍的桶數。 showImg(https://upload-images.jianshu.io/upload_images/4565148-98b22ba5ae7d9723.jpg?imageMogr2/auto-...
摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時有了較大的變化,當鏈表長度大于閾值默認為時,將鏈表轉化為紅黑樹,以減少搜索時間。有序,唯一紅黑樹自平衡的排序二叉樹。 本文是最最最常見Java面試題總結系列第三周的文章。主要內容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區別 HashMap的底層...
閱讀 1309·2021-09-27 13:56
閱讀 2340·2019-08-26 10:35
閱讀 3497·2019-08-23 15:53
閱讀 1849·2019-08-23 14:42
閱讀 1233·2019-08-23 14:33
閱讀 3562·2019-08-23 12:36
閱讀 1948·2019-08-22 18:46
閱讀 997·2019-08-22 14:06