下面这样写法是Vector线程不安全的写法:
import java.util.Vector; public class Test { private static Vector<Integer> vector = new Vector<Integer>(); public static void main(String[] args) { while (true) { for (int i = 0; i < 10; i++) { System.out.println("添加"); vector.add(i); } Thread removeThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < vector.size(); i++) { System.out.println("removeThread删除"); vector.remove(i); } } }); Thread printThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < vector.size(); i++) { System.out.println("printThread获取"); System.out.println((vector.get(i))); } } }); removeThread.start(); printThread.start(); //不要同时产生过多的线程,否则会导致操作系统假死 while (Thread.activeCount() > 20); } }
} }
尽管Vector get()、remove()、get() 方法是I同步的 但运行上面程序会出现以下错误:
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0 at java.util.Vector.get(Vector.java:744) at Test$2.run(Test.java:29) at java.lang.Thread.run(Thread.java:722) Exception in thread "Thread-14857" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0 at java.util.Vector.get(Vector.java:744) at Test$2.run(Test.java:29)
HashTable线程不安全写法:
import java.util.Hashtable; import java.util.Map; public class HashmapTest { private static Map<Integer,Integer> hashtable= new Hashtable<Integer,Integer>(); public static void main(String[] args) { while(true){ for (int i = 0; i < 10; i++) { System.out.println("添加"); hashtable.put(i, i); } Thread removeThread = new Thread(new Runnable() { @Override public void run() { Iterator it = hashtable.entrySet().iterator(); while (it.hasNext()) { Map.Entry<integer integer=""> entry=(Entry<integer integer="">) it.next(); System.out.println("delete this: "+entry.getKey()+"==="+entry.getValue()); it.remove(); } } Thread getThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < hashtable.size(); i++) { System.out.println("getThread获取"); System.out.println((hashtable.get(i))); } } }); removeThread.start(); getThread.start(); while (Thread.activeCount() > 20); } } }
会出现很多null值,但不错,因为没有那个key ,但不会报错
getThread获取 null getThread获取 null
在多线程环境中,如果不在方法调用端做额外的同步措施,使用这段仍是线程不安全的,因为如果一个线程恰好再错误的时间删除了一个元素, 导致i不在可用的话,get方法会抛出一个ArrayIndexOutOfBoundsException
import java.util.Vector; public class Test { private static Vector<Integer> vector = new Vector<Integer>(); public static void main(String[] args) { while (true) { for (int i = 0; i < 10; i++) { System.out.println("添加"); vector.add(i); } Thread removeThread = new Thread(new Runnable() { @Override public void run() { synchronized (vector) { for (int i = 0; i < vector.size(); i++) { System.out.println("removeThread删除"); vector.remove(i); } } } }); Thread printThread = new Thread(new Runnable() { @Override public void run() { synchronized (vector) { for (int i = 0; i < vector.size(); i++) { System.out.println("printThread获取"); System.out.println((vector.get(i))); } } } }); removeThread.start(); printThread.start(); //不要同时产生过多的线程,否则会导致操作系统假死 while (Thread.activeCount() > 20); } } }
Stay hungry,stay foolish !