变量在多线程下的安全性回顾

用于测试变量在多线程下的安全性.

internalNum表示方法内的数字变量,

outsideNum表示类的成员变量.


 多线程对MyObjadd()方法进行操作,结果发现,

  • 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()方法中, 是执行完了一个线程再执行另一个线程.

代码截图如下:




猜你喜欢

转载自blog.csdn.net/sanpic/article/details/79927403