实例变量非线程安全:
如果多个线程共同访问1个对象中的实例变量,则可能出现“非线程安全”问题。
public class UnSafeHasSelfPrivateNum {
private int num = 0;
public void addI(String username) {
try {
if (username.equals("a")){
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num = " + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public class UnSafeHasSelfPrivateNumThreadA extends Thread{
private UnSafeHasSelfPrivateNum numRef; public UnSafeHasSelfPrivateNumThreadA(UnSafeHasSelfPrivateNum numRef) {
this.numRef = numRef;
} @Override
public void run() {
super.run();
numRef.addI("a");
}
} public class UnSafeHasSelfPrivateNumThreadB extends Thread {
private UnSafeHasSelfPrivateNum numRef; public UnSafeHasSelfPrivateNumThreadB(UnSafeHasSelfPrivateNum numRef) {
this.numRef = numRef;
} @Override
public void run() {
super.run();
numRef.addI("b");
}
} public class ThreadRunMain {
public static void main(String[] args) {
testUnSafeHasSelfPrivateNumThread();
} public static void testUnSafeHasSelfPrivateNumThread(){
UnSafeHasSelfPrivateNum numRef = new UnSafeHasSelfPrivateNum();
UnSafeHasSelfPrivateNumThreadA athread = new UnSafeHasSelfPrivateNumThreadA(numRef);
athread.start();
UnSafeHasSelfPrivateNumThreadB bthread = new UnSafeHasSelfPrivateNumThreadB(numRef);
bthread.start();
}
}
运行结果:
a的值本应该是100,却变成了200. 用synchronized关键字解决问题:
public class UnSafeHasSelfPrivateNum {
private int num = 0;
synchronized public void addI(String username) {
try {
if (username.equals("a")){
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num = " + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
在两个线程访问同一个对象中的同步方法时是线程安全的,先执行a,在执行b。