关于volatile

shfzhzhr 2008-04-01 05:01:49
public class Volatile implements Runnable {
// not marked as ‘volatile’, but it should be!
private int value;
private volatile boolean missedIt;
// doesn’t need to be volatile-doesn’t change
private long creationTime;

public Volatile() {
value = 10;
missedIt = false;
creationTime = System.currentTimeMillis();
}

public void run() {
print("entering run()");
// each time, check to see if ‘value’ is different
while (value<20) {
// Used to break out of the loop if change to
// value is missed.

if (missedIt) {
int currValue = value;
// Simply execute a synchronized statement on an
// arbitrary object to see the effect.
Object lock = new Object();
synchronized (lock) {
//do nothing
}
int valueAfterSync = value;
print("in run() - see value=" + currValue +", but rumor has it that it changed!");
print("in run() - valueAfterSync=" + valueAfterSync);
break;
}
}
print("leaving run()");
}

public void workMethod() throws InterruptedException {
print("entering workMethod()");
print("in workMethod() - about to sleep for 2 seconds");
Thread.sleep(2000);
value = 50;
print("in workMethod() - just set value=" + value);
print("in workMethod() - about to sleep for 5 seconds");
Thread.sleep(5000);
missedIt = true;
print("in workMethod() - just set missedIt=" + missedIt);
print("in workMethod() - about to sleep for 3 seconds");
Thread.sleep(3000);
print("leaving workMethod()");
}

private void print(String msg) {
// This method could have been simplified by using
// functionality present in the java.text package,
// but did not take advantage of it since that package
// is not present in JDK1.0.
long interval = System.currentTimeMillis() - creationTime;

String tmpStr = " " + (interval / 1000.0) + "000";
int pos = tmpStr.indexOf(".");
String secStr = tmpStr.substring(pos - 2, pos + 4);
String nameStr = " " +Thread.currentThread().getName();
nameStr = nameStr.substring(nameStr.length() - 8,nameStr.length());
System.out.println(secStr + " " + nameStr + " :" + msg);
}

public static void main(String[] args) {
try {
Volatile vol = new Volatile();
// slight pause to let some time elapse
Thread.sleep(100);
Thread t = new Thread(vol);
t.start();
// slight pause to allow run() to go first
Thread.sleep(100);
vol.workMethod();
} catch (InterruptedException x) {
System.err.println("one of the sleeps was interrupted");
}
}

}

在这个程序中成员变量没有用volatile修饰
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
那么这个程序的期望结果应该是:
1: 0.170 Thread-0: entering run()

2: 0.280 main: entering workMethod()

3: 0.610 main: in workMethod() - about to sleep for 2 seconds

4: 2.700 main: in workMethod() - just set value=50

5: 2.700 main: in workMethod() - about to sleep for 5 seconds

6: 7.750 main: in workMethod() - just set missedIt=true

7: 7.750 main: in workMethod() - about to sleep for 3 seconds

8: 7.750 Thread-0: in run() - see value=10, but rumor has it that it changed!

9: 7.750 Thread-0: in run() - valueAfterSync=50

10: 7.750 Thread-0: leaving run()

11: 10.710 main: leaving workMethod()

但是在jdk_1.6的环境下编译运行中有没有volatile结果都是一样的,如下:
0.093 Thread-0 :entering run()
0.203 main :entering workMethod()
0.203 main :in workMethod() - about to sleep for 2 seconds
2.203 Thread-0 :leaving run()
2.203 main :in workMethod() - just set value=50
2.203 main :in workMethod() - about to sleep for 5 seconds
7.203 main :in workMethod() - just set missedIt=true
7.203 main :in workMethod() - about to sleep for 3 seconds
10.203 main :leaving workMethod()
也就是说有没有volatile修饰,value的值都是和内存中的值同步的, 为什么?
是因为JIT的原因么?
...全文
38 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
shfzhzhr 2008-04-01
  • 打赏
  • 举报
回复
有没有人帮帮忙啊

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧