今天看了一下网上说linkedlist是线程不安全的 ,多线程下会抛出java.util.ConcurrentModificationException异常
其实不对 ,linkedlist线程不安全不假 ,但是并不会抛出异常
源码: add()方法
/** * Appends the specified element to the end of this list. * * <p>This method is equivalent to {@link #addLast}. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ public boolean add(E e) { linkLast(e); return true; }
/** * Links e as last element. */ void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
其实是没有任何抛出异常的方法
而在其内部类ListIterator中
public void add(E e) { checkForComodification(); lastReturned = null; if (next == null) linkLast(e); else linkBefore(e, next); nextIndex++; expectedModCount++; }才有校验
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
所以多线程下正常的add()操作并不会抛出异常, 而使用ListIterator才会抛出异常
测试代码 : 使用ListIterator
public class Test1 { private final LinkedList<Integer> list = new LinkedList<Integer>(); public Test1() { Thread add1 = new Thread(new Runnable() { @Override public void run() { ListIterator<Integer> integerListIterator = list.listIterator(); int number = 0; while (true) { if (number == 10) number = 0; // System.out.println("Writing " + number); integerListIterator.add(number); number++; System.out.flush(); try { Thread.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); Thread add2 = new Thread(new Runnable() { @Override public void run() { ListIterator<Integer> integerListIterator = list.listIterator(); int number = 100; while (true) { if (number > 119) { number = 100; } integerListIterator.add(number); number++; try { Thread.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); Executors.newCachedThreadPool().execute(add1); Executors.newCachedThreadPool().execute(add2); } /** * @param args */ public static void main(String[] args) { Test1 test = new Test1(); } }Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:953)
at java.util.LinkedList$ListItr.add(LinkedList.java:941)
at main.Test1$1.run(Test1.java:29)
at java.lang.Thread.run(Thread.java:745)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
正常add():
public class Test1 { private final LinkedList<Integer> list = new LinkedList<Integer>(); public Test1() { Thread add1 = new Thread(new Runnable() { @Override public void run() { int number = 0; while (true) { if (number == 10) number = 0; // System.out.println("Writing " + number); list.add(number); number++; System.out.flush(); try { Thread.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); Thread add2 = new Thread(new Runnable() { @Override public void run() { int number = 100; while (true) { if (number > 119) { number = 100; } list.add(number); number++; try { Thread.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); Executors.newCachedThreadPool().execute(add1); Executors.newCachedThreadPool().execute(add2); } /** * @param args */ public static void main(String[] args) { Test1 test = new Test1(); } }没有抛出异常