線程不安全的的集合有(HashSet,TreeSet,ArrayList,ArrayDeque,LinkedList,HashMap,TreeMap);java
線程安全的集合有(Vector,HashTable);安全
Java給你的保證的線程安全,是說它的方法是執行是排它的,而不是對這個對象自己的屢次調用狀況下,仍是安全的。this
1)線程不安全案例:spa
public class ListThread implements Runnable { String name; List<String> l; ListThread(String name, List<String> l) { this.name = name; this.l = l; } public void run() { System.out.println(name + "start"); for(int i = 0; i<6; i++){ l.add(name + ".add"); System.out.println(name + " list size is " + l.size()); try { Thread.sleep(10); } catch(InterruptedException e) { System.out.println(e.getMessage()); } } } public static void main(String args[]) throws InterruptedException { List<String> l = new ArrayList<String>(); ListThread hello1 = new ListThread("hello1", l); ListThread hello2 = new ListThread("hello2", l); ListThread hello3 = new ListThread("hello3", l); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start(); } }
執行結果:.net
hello1start
hello1 list size is 1
hello3start
hello3 list size is 2
hello2start
hello2 list size is 3
hello1 list size is 4
hello3 list size is 5
hello2 list size is 6
hello1 list size is 7
hello2 list size is 9
hello3 list size is 9
hello1 list size is 10
hello3 list size is 11
hello2 list size is 12
hello1 list size is 13
hello3 list size is 14
hello2 list size is 14
hello1 list size is 15
hello3 list size is 17
hello2 list size is 17線程
----以上結果每一個線程執行6次list添加,結果list長度只有17個,數據丟失,線程不安全。code
2)線程安全案例:對象
public class VectorThread implements Runnable { String name; Vector<String> v; VectorThread(String name, Vector<String> v) { this.name = name; this.v = v; } public void run() { System.out.println(name + "start"); for(int i = 0; i<6; i++){ v.add(name + ".add"); System.out.println(name + " vector size is " + v.size()); try { Thread.sleep(10); } catch(InterruptedException e) { System.out.println(e.getMessage()); } } } public static void main(String args[]) throws InterruptedException { Vector<String> v = new Vector<String>(); VectorThread hello1 = new VectorThread("hello1", v); VectorThread hello2 = new VectorThread("hello2", v); VectorThread hello3 = new VectorThread("hello3", v); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start(); } }
執行結果:get
hello2start
hello2 vector size is 1
hello3start
hello1start
hello1 vector size is 3
hello3 vector size is 2
hello1 vector size is 5
hello3 vector size is 5
hello2 vector size is 6
hello1 vector size is 7
hello2 vector size is 8
hello3 vector size is 9
hello3 vector size is 12
hello2 vector size is 11
hello1 vector size is 11
hello3 vector size is 14
hello2 vector size is 15
hello1 vector size is 14
hello3 vector size is 17
hello2 vector size is 17
hello1 vector size is 18io
--------------線程安全,結果執行不管多少次,最後vector的長度都是18,數據添加完整安全,可是長度在線程搶佔時仍是有size相同的狀況,須要在外圍另外添加synchronized
3)外圍加鎖後的線程安全案例
public class VectorThread2 implements Runnable { String name; Vector<String> v; VectorThread2(String name, Vector<String> v) { this.name = name; this.v = v; } public void run() { System.out.println(name + "start"); for(int i = 0; i<6; i++){ synchronized(v){ v.add(name + ".add"); System.out.println(name + " vector size is " + v.size()); } try { Thread.sleep(10); } catch(InterruptedException e) { System.out.println(e.getMessage()); } } } public static void main(String args[]) throws InterruptedException { Vector<String> v = new Vector<String>(); VectorThread2 hello1 = new VectorThread2("hello1", v); VectorThread2 hello2 = new VectorThread2("hello2", v); VectorThread2 hello3 = new VectorThread2("hello3", v); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start(); } }
執行結果:
hello2start
hello2 vector size is 1
hello2 vector size is 2
hello2 vector size is 3
hello2 vector size is 4
hello1start
hello1 vector size is 5
hello2 vector size is 6
hello1 vector size is 7
hello2 vector size is 8
hello1 vector size is 9
hello3start
hello3 vector size is 10
hello1 vector size is 11
hello3 vector size is 12
hello1 vector size is 13
hello3 vector size is 14
hello1 vector size is 15
hello3 vector size is 16
hello3 vector size is 17
hello3 vector size is 18
----------------------這樣不管執行多少次既不會線程搶佔,也不會數據丟失
4)使用synchronizedXxx封裝後集合線程安全案例(效果和Vector相似)
public class SynchronizedListRight implements Runnable { String name; List<String> list; SynchronizedListRight(String name, List<String> list) { this.name = name; this.list = list; } public void run() { System.out.println(name + "start"); for(int i = 0; i<6; i++){ synchronized(list){ list.add(name + ".add"); System.out.println(name + " list size is " + list.size()); } try { Thread.sleep(10); } catch(InterruptedException e) { System.out.println(e.getMessage()); } } } public static void main(String args[]) throws InterruptedException { List<String> list = Collections.synchronizedList(new ArrayList<String>()); SynchronizedListRight hello1 = new SynchronizedListRight("hello1", list); SynchronizedListRight hello2 = new SynchronizedListRight("hello2", list); SynchronizedListRight hello3 = new SynchronizedListRight("hello3", list); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start(); } }
執行結果:
hello3start
hello1start
hello3 list size is 1
hello2start
hello1 list size is 2
hello2 list size is 3
hello1 list size is 4
hello3 list size is 5
hello2 list size is 6
hello1 list size is 7
hello3 list size is 8
hello2 list size is 9
hello2 list size is 10
hello3 list size is 11
hello1 list size is 12
hello2 list size is 13
hello3 list size is 14
hello1 list size is 15
hello1 list size is 16
hello2 list size is 17
hello3 list size is 18
----------效果和第三種案例同樣