下面这样写法是线程不安全的写法
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)
at java.lang.Thread.run(Thread.java:722)
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);
}
}
}
</integer></integer>
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);
}
}
}