1. 程式人生 > >Java多線程系列五——列表類

Java多線程系列五——列表類

多線程操作 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多線程系列五——列表類