Java多線程系列五——列表類
阿新 • • 發佈:2017-07-08
多線程操作 ide body 得到 multi 機制 rac adlist ada
參考資料:
http://xxgblog.com/2016/04/02/traverse-list-thread-safe/
一些列表類及其特性
類 | 線程安全 | Iterator | 特性 | 說明 |
Vector | 是 | fail-fast | 內部方法用synchronized修飾,因此執行效率較低 |
1. 線程安全的列表類並不意味著調用它的代碼就一定線程安全 2. 只有CopyOnWriteArrayList能支持在遍歷時修改列表元素 |
ArrayList | 否 | fail-fast | 在多線程環境中使用不當易出錯 | |
Collections.synchronizedList | 是 | fail-fast | Collections.synchronizedList可以得到線程安全的列表,與Vector類似 | |
CopyOnWriteArrayList | 是 | fail-safe | 每個線程先復制一份並把地址指向新list,在新的list上操作,因此最終結果未必符合預期,適用於經常需要遍歷但很少修改的場景 |
以下代碼模擬多線程環境下,各個類Iterator機制的表現
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch;/** * http://xxgblog.com/2016/04/02/traverse-list-thread-safe/ * * @Description: 多線程操作列表 */ public class ThreadListTest { public void multipleThreadArrayList(final List<Integer> list) throws InterruptedException { int count = 10; for (int i = 0; i < count; i++) { list.add(i); } CountDownLatch countDownLatch= new CountDownLatch(2); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for (Integer integer : list) { System.out.println(integer); } countDownLatch.countDown(); } }).start(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getId() + " remove " + list.remove(0)); countDownLatch.countDown(); } }).start(); countDownLatch.await(); } public static void main(String[] args) throws InterruptedException { ThreadListTest test = new ThreadListTest(); List<Integer> list; list = new Vector<>();// Vector只保證內部方法線程安全 list = new ArrayList<>();// ArrayList效率較Vector,但非線程安全 list = Collections.synchronizedList(new ArrayList<>());// Collections.synchronizedList與Vector有異曲同工之妙 list = new CopyOnWriteArrayList<>();// CopyOnWriteArrayList線程安全:每個線程先復制一份並把地址指向新list,在新的list上操作,因此最終結果未必符合預期 test.multipleThreadArrayList(list); System.out.println(list.toString()); } }
Java多線程系列五——列表類