总览
- 多线程+对象在方法内部
- 多线程+对象在方法外部
- 多线程+单对象+synchronized
- 多线程+多对象+synchronized
- 多线程+synchronized+static
- 多线程+单对象+synchronized+static
- 多线程+多对象+synchronized+static
多线程+对象在方法外部(例子)
(1)HasSelPrivateNum.java类
public class HasSelPrivateNum {
private int num = 0;//这里将num变量放到了addI()方法外部
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();
}
}
}
(2)ThreadA.java
public class ThreadA extends Thread {
private HasSelPrivateNum numRef;
public ThreadA(HasSelPrivateNum numRef) {
super();
this.numRef = numRef;
}
@Override
public void run() {
super.run();
numRef.addI("a");
}
}
(3)ThreadB.java
public class ThreadB extends Thread {
private HasSelPrivateNum numRef;
public ThreadB(HasSelPrivateNum numRef) {
super();
this.numRef = numRef;
}
@Override
public void run() {
super.run();
numRef.addI("b");
}
}
(4)Run.java
public class Run {
public static void main(String[] args) {
HasSelPrivateNum numRef = new HasSelPrivateNum();
ThreadA a = new ThreadA(numRef);
a.start();
ThreadB b = new ThreadB(numRef);
b.start();
}
}
运行结果
总结
-
从这个运行结果中可以看出这两个线程交叉执行了,出现了值覆盖的情况,本来
a num=100
,却被线程B给覆盖成了a num=200
,出现了非线程安全问题。 -
可见,多个线程访问一个对象的实例变量,可能出现非线程安全问题
-
用线程访问的对象中如果有多个实例变量,则运行结果有可能出现交叉的情况,如果对象仅有1个实例变量,则有可能出现覆盖的情况,上面例子就是覆盖的情况。
-
解决这个情况,只需添加
synchronized
关键字,也就是多线程+单对象+synchronized,下一篇有详细说明。