网上看到好多定论说是局部变量就是线程安全的。但是我觉得对大家都造成了一些误解,例如
以下;
package Test;
public class Demo_5 {
public static void main(String[] args) {
//创建一个窗口
TicketWindow tw1=new TicketWindow();
//使用三个线程同时启动
Thread t1=new Thread(tw1);
Thread t2=new Thread(tw1);
Thread t3=new Thread(tw1);
t1.start();
t2.start();
t3.start();
}
}
//售票窗口类
class TicketWindow implements Runnable{
private int nums=2000; //一共2000张票
public void test() {
int test;
boolean me;
while(true){
test=nums--;
synchronized (this) {
me=test>0;
}
if(me){ //先判断是否还有票
//Thread.currentThread().getName()得到当前线程的名字
System.out.println(Thread.currentThread().getName()+"在售出第"+test+"张票"); //显示售票信息
//出票的速度是一秒出一张
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break; //售票结束
}
}
}
@Override
public void run() {
test();
}
}
上面是一个非线程安全类,运行结果如下:
Thread-2在售出第1998张票
Thread-0在售出第2000张票
Thread-1在售出第1999张票
Thread-1在售出第1997张票
Thread-2在售出第1995张票
Thread-0在售出第1996张票
Thread-0在售出第1994张票
Thread-1在售出第1994张票
Thread-2在售出第1994张票
Thread-2在售出第1993张票
Thread-0在售出第1992张票
Thread-1在售出第1991张票
Thread-0在售出第1990张票
Thread-1在售出第1989张票
Thread-2在售出第1988张票
Thread-1在售出第1987张票
同时售出相同第几张票,也就是说线程不安全,我们追根溯本:来找下原因,虽然
int test;boolean me;这两个都是局部变量,但是nums是成员变量,即如果局部变量引用了非可变成员变量,依然线程不安全!
再看下面这个事例:
package Test;
public class Demo_5 {
public static void main(String[] args) {
//创建一个窗口
TicketWindow tw1=new TicketWindow();
//使用三个线程同时启动
Thread t1=new Thread(tw1);
Thread t2=new Thread(tw1);
Thread t3=new Thread(tw1);
t1.start();
t2.start();
t3.start();
}
}
//售票窗口类
class TicketWindow implements Runnable{
private int nums=2000; //一共2000张票
public void test() {
int test;
boolean me;
while(true){
synchronized (this) {
test=nums--;
me=test>0;
}
if(me){ //先判断是否还有票
//Thread.currentThread().getName()得到当前线程的名字
System.out.println(Thread.currentThread().getName()+"在售出第"+test+"张票"); //显示售票信息
//出票的速度是一秒出一张
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break; //售票结束
}
}
}
@Override
public void run() {
test();
}
}
运行结果如下:
Thread-0在售出第2000张票
Thread-2在售出第1998张票
Thread-1在售出第1999张票
Thread-1在售出第1995张票
Thread-0在售出第1997张票
Thread-2在售出第1996张票
Thread-1在售出第1994张票
Thread-0在售出第1992张票
Thread-2在售出第1993张票
Thread-1在售出第1991张票
Thread-0在售出第1990张票
Thread-2在售出第1989张票
Thread-1在售出第1986张票
Thread-2在售出第1988张票
Thread-0在售出第1987张票
Thread-1在售出第1985张票
Thread-0在售出第1983张票
Thread-2在售出第1984张票
则没有重复的,则该线程安全