您的位置:首页 > 编程语言 > Java开发

Java原子操作与多线程操作测试一例

2016-12-30 18:04 197 查看
从别处发现这个有意思的测试, 加不加volatile来修饰变量是有不同的, 具体原因请详究Java的内存模型/线程运行机制/volatile关键字.

Java中的赋值, 除了long和double之外均为原子操作, 也就是说, 在多线程环境中, 在很小很小的几率下会拿到一个既非原值, 又不是其他所赋值的"半个变量". 但是这种情况只是理论上, 在现实中非常罕见, 因为Java强烈建议虚拟机(有很多Java虚拟机, 有些并非官方实现)实现时将long和double都实现成原子操作, 并且很多虚拟机都遵从了Java的建议.

直接贴代码:

/**
* 从别处发现这个有意思的测试, 加不加volatile来修饰变量是有不同的, 具体原因请详究Java的内存模型/线程运行机制/volatile关键字
*
* 由于check()方法中的if判断不是原子操作, 所以是会打印Error的
*
* @author David Ding
*
*/
public class ThreadSharedField {
//	private long shared = 0;
private volatile long shared = 0;

public void set0() {
shared = 0;
}

public void set1() {
shared = 1;
}

public void check() {
if (0 != shared && 1 != shared) {
System.err.println("Error");
}
}

public static void main(final String[] args) {
final ThreadSharedField v = new ThreadSharedField();

// 线程 1:设置 b = 0
final Thread set0Th = new Thread() {
public void run() {
while (true) {
v.set0();
}
};
};
set0Th.start();

// 线程 2:设置 b = 1
final Thread set1Th = new Thread() {
public void run() {
while (true) {
v.set1();
}
};
};
set1Th.start();

// 线程 3:检查 0 != b && 1 != b
final Thread testTh = new Thread() {
public void run() {
while (true) {
v.check();
}
};
};
testTh.start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息