ArrayList 的线程安全问题
2015-07-04 16:16
253 查看
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.ListIterator; public class ArrayListTest { /** * @param ArrayList * 的线程安全问题 * * 加锁解决异常 java.util.ConcurrentModificationException * 和java.lang.IndexOutOfBoundsException */ public static void main(String[] args) { List<Double> data0 = Collections .synchronizedList(new ArrayList<Double>()); data0.add(1.0); data0.add(4.0); data0.add(5.0); data0.add(8.0); ForList tlist = new ForList(data0); ListAddRemove Lar = new ListAddRemove(data0); ForList2 tlist2 = new ForList2(data0); IteratorAddRemove Iar = new IteratorAddRemove(data0); Thread t1 = new Thread(tlist); // list 循环方法: for (int i = 0; i < l; i++); Thread t2 = new Thread(Lar);// list 加减元素; Thread t3 = new Thread(tlist2); // Iterator 循环方法:for (Double data : data0) ; Thread t4 = new Thread(Iar);// Iterator 加减元素; int set = 1;// 模式选择 switch (set) { case 1: t1.start();// list 循环方法 t2.start();// list 加减元素; break; case 2: t3.start();// Iterator 循环方法 t4.start();// Iterator 加减元素; break; case 3: t1.start();// list 循环方法 t4.start();// Iterator 加减元素; break; case 4: t3.start();// Iterator 循环方法 t2.start();// list 加减元素; break; } } } class ForList implements Runnable// extends Thread { /** * list 循环方法 * */ public ForList(List<Double> data0) { this.data0 = data0; } private List<Double> data0; private int count = 100; public void run() { while (count > 0) { count--; synchronized (data0) { int l = data0.size(); for (int i = 0; i < l; i++) { Double data = data0.get(i); System.out.println(Thread.currentThread().getName() + "data: " + data); } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } if (count == 0) { System.out .println("——————————————————————————————————————————————————————"); } } } } class ListAddRemove implements Runnable { private List<Double> data0; private int count = 1000; double i = 9; /** * list 加减元素 * */ public ListAddRemove(List<Double> data0) { this.data0 = data0; } public void run() { while (count > 0) { synchronized (data0) { count--; data0.remove(i - 1); try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (data0) { data0.add(i); i++; } } } } class ForList2 implements Runnable// extends Thread { /** * Iterator 循环方法 * */ public ForList2(List<Double> data0) { this.data0 = data0; } private List<Double> data0; private int count = 100; public void run() { while (count > 0) { count--; synchronized (data0) { for (Double data : data0) { System.out.println(Thread.currentThread().getName() + "data: " + data); } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } if (count == 0) { System.out .println("——————————————————————————————————————————————————————"); } } } } class IteratorAddRemove implements Runnable { private List<Double> data0; private int count = 1000; double i = 9; /** * * Iterator 加减元素 */ public IteratorAddRemove(List<Double> data0) { this.data0 = data0; } public void run() { while (count > 0) { ListIterator<Double> li = data0.listIterator(); count--; synchronized (data0) { while (li.hasNext()) { double j = li.next(); if (i - 1 == j) { li.remove(); } } try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (data0) { li.add(i); } i++; } } }
ArrayList 的方法是线程不安全的,使用不当就会产生异常 java.util.ConcurrentModificationException 和 java.lang.IndexOutOfBoundsException
针对list方法和Iterator方法的混合使用,测试发现加锁能有效防止两种异常的产生
相关文章推荐