Java5 多線程(九)–jdk1.5同步集合

來源:互聯網
上載者:User
在JDK1.5之前沒有推出同步集合的時候,可以通過Conllections集合工具類的synchronized+集合名稱如:synchronizedSet(Set),現在不需要這種方式了使用 ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet,ConcurrentLinkedQueue等這些集合即可.          1>線程不安全的集合出現的問題,死迴圈.Race Condition(也叫做資源競爭),是多線程編程中比較頭疼的問題特別是Java多線程當中,經常會因為多線程同時訪問相同的共用資料,而造成資料的不一致性,為瞭解決這個問題通常來說需要加上同步標識synchronized,來保證資料串列的訪問,但是synchronized是個效能殺手,過多的使用會導致效能下降,特別是擴充性下降,使得系統不能使用多個CPU資源,這是效能測試當中經常遇到的問題.        然而有一個公司的ERP系統出現了問題,然後就叫Java的進階工程師來解決,該工程師通發現當500個並發用訪問的時候,居然把所有的CPU都壓得滿滿的,通過過DTrace for Java工具發現很多CPU都在做同一件事,那就是不停的執行一條語句(HashMap.get()方法).這是為什麼呢?我們知道遍曆Map集合的時候,是這樣的情形(下面只是虛擬碼):while(hasNext()){    //每當迴圈一次cursor加1    //假設該集合裡面有4個元素(count=4),如果迴圈到最後一次了cursor=4,就在此時另一個線程//跑來把集合裡面的一個元素給刪除了(remove()),這時候count=3了,這時候上一個線程接著執行//它會去判斷hasNext(),但是count!=cursor了,而本來是相等的.這樣就是死迴圈了. }hasNext(){    if(cursor==count){        return false;//不需要再迴圈了    }    return true;}  總結: 線程不安全的集合,如果多個線程同時對其進行添加和刪除操作, 有可能會出現致命的錯誤. 
        2>HashSet和HashMap關係通過查看HashSet源碼: public HashSet() {map = new HashMap<E,Object>();

} 發現HashSet實際上就是通過HashMap來實現的,不過它只用到了HashMap的key         3>線程不安全集合還有另一個隱患public static void main(String[] args) {

        //Collection users = new CopyOnWriteArrayList();        Collection users = new ArrayList();         users.add(new User("張三",28));            users.add(new User("李四",25));                    users.add(new User("王五",31));            Iterator itrUsers = users.iterator();        while(itrUsers.hasNext()){            System.out.println("aaaa");            User user = (User)itrUsers.next();            if("張三".equals(user.getName())){                users.remove(user);            } else {                System.out.println(user);                            }        }

    }

運行程式發現出現異常:


這是為什麼?跟進AbstractList 343行:


分析如下:我們來看一下這個

while(itrUsers.hasNext()){    User user = (User)itrUsers.next();    if("張三".equals(user.getName())){        users.remove(user);    } else {        System.out.println(user);    }}查看hasNext源碼:


 如果把 if("張三".equals(user.getName()))改成 if("王五".equals(user.getName()))輸出結果如下:


出現了第一次出現的異常,分析如下:當第一迴圈執行到next()時候expectedModCount=3 modCount=3 cursor=1,size()=3當第二迴圈執行到next()時候expectedModCount=3 modCount=3 cursor=2,size()=3當第三迴圈執行到next()時候expectedModCount=3 modCount=4 cursor=3,size()=2發現cursor任然不等於size(),迴圈人仍在繼續,最後發現expectedModCount!=modCount拋出異常.所以控制太輸出這樣的結果. 要想迭代的時候同時操作集合可以使用JDK1.5提供的安全執行緒的集合,只需要把集合改成如下即可:Collection users = new CopyOnWriteArrayList();

轉載請註明出處 : http://blog.csdn.net/johnny901114/article/details/8696032

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.