下面這樣寫法是線程不安全的寫法
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);
}
}
}