用于测试变量在多线程下的安全性.
internalNum表示方法内的数字变量,
outsideNum表示类的成员变量.
多线程对MyObj的add()方法进行操作,结果发现,
- internalNum 的值会始终为1, 不会因为多线程而增加到2.
- outsideNum却打印出了许多相同的值.打印出了别的线程所赋的值.
代码如下
public class FieldInThreads {
public static void main(String[] args) {
MyObj obj = new MyObj();
for (int i = 0; i < 1000; i++) {
Thread thread = new MyThreads(obj);
thread.start();
}
}
}
class MyObj {
private int outsideNum = 0;
public void add() throws InterruptedException {
int internalNum = 0;
Thread.sleep(100);
internalNum++;
outsideNum++;
System.out.println(Thread.currentThread().getName() + "\t:\t" + outsideNum + "\t:\t" + internalNum);
if(internalNum>=2) {
System.err.println("Error internal Num: " + internalNum);
}
}
public synchronized void synAdd() throws InterruptedException {
add();
}
}
class MyThreads extends Thread {
MyObj obj;
public MyThreads(MyObj obj) {
this.obj = obj;
}
@Override
public void run() {
try {
obj.add(); //替换为-->obj.synAdd();那么打印结果, 线程名几乎递减(不是绝对的递减), outsideNum的值递增
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果截图如下:
但是如果Threads方法调用synAdd方法, 相当于给add()加上了方法锁, 则
- 线程名接近递减, 但大趋势是递减.
- outsideNum 值会是完全逐步递增,
- 执行时间会很长, 因为在add()方法中, 是执行完了一个线程再执行另一个线程.
代码截图如下: