java多线程2:局部变量的线程安全,实列变量的非线程安全
“非线程安全“就是在多个线程访问同一个对象的实例变量进行并发访问时候发生,产生的后果就是”脏读“,也就是取到的数据其实是被修改过的。
a.多线程访问局部变量是线程安全的。
package multiThread.synchro;
public class OneNumber {
public void receiveUserName(String userName) {
int num = 0;
if (userName.equals("a")) {
num = 100;
} else {
num = 200;
}
System.out.println("userName:" + userName + " 数字是:" + num);
}
}
package multiThread.synchro;
public class AThread extends Thread {
private OneNumber oneNumber;
public AThread(OneNumber oneNumber) {
this.oneNumber = oneNumber;
}
public void run() {
oneNumber.receiveUserName("a");
}
}
package multiThread.synchro;
public class BThread extends Thread {
private OneNumber oneNumber;
public BThread(OneNumber oneNumber) {
this.oneNumber = oneNumber;
}
public void run() {
oneNumber.receiveUserName("b");
}
}
package multiThread.synchro;
public class Main {
public static void main(String[] args) {
OneNumber oneNumber = new OneNumber();
AThread aThread = new AThread(oneNumber);
BThread bThread = new BThread(oneNumber);
aThread.start();
bThread.start();
}
}
控制台:
b.如果对上边OneNumber类稍作修改,将局部变量num变为实例变量:
package multiThread.synchro;
public class OneNumber {
int num = 0;
public void receiveUserName(String userName) {
if (userName.equals("a")) {
num = 100;
} else {
num = 200;
}
System.out.println("userName:" + userName + " 数字是:" + num);
}
}
控制台:
c.如何解决并发造成的访问实例变量的非线程安全问题:
加关键字:synchronized
package multiThread.synchro;
public class OneNumber {
int num = 0;
synchronized public void receiveUserName(String userName) {
if (userName.equals("a")) {
num = 100;
} else {
num = 200;
}
System.out.println("userName:" + userName + " 数字是:" + num);
}
}
控制台: