情形一:成员变量被多线程共享
import java.util.ArrayList;
import java.util.List;
public class ThreadUnSafeTest {
static final int THREAD_NUMBER = 2;
static final int LOOP_NUMBER = 200;
public static void main(String[] args) {
//同一个对象被多个线程共享
final ThreadUnSafe test = new ThreadUnSafe();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(()->{
test.method1(LOOP_NUMBER);
},"Thread" + (i + 1)).start();
}
}
}
class ThreadUnSafe{
List<String> list = new ArrayList<String>();
public void method1(int loopNumber){
for (int i = 0; i < loopNumber; i++) {
method2();
method3();
}
}
public void method2(){
list.add("1");
}
public void method3(){
list.remove(0);
}
}
此代码有可能造成以下异常:
Exception in thread "Thread1" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.remove(ArrayList.java:496)
at ThreadUnSafe.method3(ThreadUnSafeTest.java:35)
at ThreadUnSafe.method1(ThreadUnSafeTest.java:26)
at ThreadUnSafeTest.lambda$main$0(ThreadUnSafeTest.java:13)
at java.lang.Thread.run(Thread.java:748)
原因:因为多个线程共享test对象中的list成员变量,同时对list进行add和remove操作造成的,List是线程不安全的类
。
情形二:使用局部变量list
public class ThreadUnSafeTest {
static final int THREAD_NUMBER = 2;
static final int LOOP_NUMBER = 200;
public static void main(String[] args) {
final ThreadSafe test = new ThreadSafe();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(()->{
test.method1(LOOP_NUMBER);
},"Thread" + (i + 1)).start();
}
}
}
class ThreadSafe{
public void method1(int loopNumber){
//局部变量,list存在于每个线程的私有栈帧中,不会构成临界资源
List<String> list = new ArrayList<String>();
for (int i = 0; i < loopNumber; i++) {
method2(list);
method3(list);
}
}
public void method2(List<String> list){
list.add("1");
}
public void method3(List<String> list){
list.remove(0);
}
}
运行此代码将不会出现错误。
原因:虽然多个线程共享test对象,但是每个线程在栈帧
中拥有自己的list对象,不构成临界区
,不会发成线程不安全问题。