当前位置:编程学习 > JAVA >>

java中对象或者数组用volatile修饰有什么用?

一般类型变量用volatile修饰的作用都清楚,http://www.ibm.com/developerworks/cn/java/j-jtp06197.html,除了这里面介绍的“一次性安全发布”,将volatile修饰对象或数组的作用是什么呢?
例如,java.io.BufferedInputStream类中protected volatile byte buf[];  数组buf用volatile修饰;
java.io.FilterInputStream类中protected volatile InputStream in;   in用volatile修饰。
jdk中这样写好处在哪里? java volatile java volatile --------------------编程问答-------------------- Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。

这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。

而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。

使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。

由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。 

就跟C中的一样 禁止编译器进行优化~~~~ --------------------编程问答-------------------- 楼上+1,主要是为了线程同步的 --------------------编程问答-------------------- 我也很想知道这个问题, 比如 volatile boolean flag; 为了让多线程操作的时候,能同步。 但是volatile Object object 这样,目的是什么?  难道多线程object被修改了,会不同步?  --------------------编程问答--------------------  volatile 能够保障多个线程访问同一个变量时候,可以获取到最新的一个结果。 --------------------编程问答--------------------
引用 3 楼 Kanepan 的回复:
我也很想知道这个问题, 比如 volatile boolean flag; 为了让多线程操作的时候,能同步。 但是volatile Object object 这样,目的是什么?  难道多线程object被修改了,会不同步?



http://ifeve.com/concurrency-visibility/ --------------------编程问答-------------------- 多线程问题,就要上并发编程网 --------------------编程问答--------------------
引用 6 楼 ticmy 的回复:
多线程问题,就要上并发编程网


谢谢你的网站 --------------------编程问答-------------------- 我来回答我自己的问题



package com.kane;

/**
 * @author ThrilleR 
 * 必须要加上 -server才能生效,因为在-server下程序运行速度很快做过优化,才会出现stop不了的情况。在Object上加上volatile就可见了。
 * 
 */
public class VolatileObjectTest implements Runnable {
private ObjectA a; // 加上volatile 就可以正常结束While循环了

public VolatileObjectTest(ObjectA a) {
this.a = a;
}

public ObjectA getA() {
return a;
}

public void setA(ObjectA a) {
this.a = a;
}

@Override
public void run() {
long i = 0;
while (a.isFlag()) {
i++;
}
System.out.println("stop My Thread " + i);
}

public void stop() {
a.setFlag(false);
}

public static void main(String[] args) throws InterruptedException {
 // 如果启动的时候加上-server 参数则会 输出 Java HotSpot(TM) Server VM
System.out.println(System.getProperty("java.vm.name"));

VolatileObjectTest test = new VolatileObjectTest(new ObjectA());
new Thread(test).start();

Thread.sleep(1000);
test.stop();
Thread.sleep(1000);
System.out.println("Main Thread " + test.getA().isFlag());
}

static class ObjectA {
private boolean flag = true;

public boolean isFlag() {
return flag;
}

public void setFlag(boolean flag) {
this.flag = flag;
}

}
}

--------------------编程问答--------------------
引用 1 楼 feier00 的回复:
Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。

这样……


很精确了 --------------------编程问答--------------------
引用 8 楼 Kanepan 的回复:
我来回答我自己的问题


Java code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061package com.kane; /** * @author ThrilleR  * 必须要加……



楼住 我测试了下你的程序 好像不行啊  

Java HotSpot(TM) Client VM
stop My Thread 610845501
Main Thread false
Process exited with exit code 0.

我没有加volatile关键字,程序也正常结束了......... --------------------编程问答-------------------- 楼主不在吗? --------------------编程问答--------------------
引用 11 楼 Yweige2010 的回复:
楼主不在吗?



你得这么运行:
java -server VolatileObjectTest 
java -client VolatileObjectTest --------------------编程问答-------------------- 在多线程的环境中,可以保证变量值的一致性 --------------------编程问答-------------------- 谢谢各位的回答,ticmy提供的网站很好,Kanepan的代码又让我明白了client vm和server vm的区别,不过现在还没有找到数组用volatile修饰的详解例子,想了下应该和频繁修改数组引用有关,http://ifeve.com/volatile-array-visiblity/      这里面有解释,不过没怎么看懂。 --------------------编程问答-------------------- 多线程,单例的实现。
mark --------------------编程问答--------------------
引用 15 楼 Bumpking 的回复:
多线程,单例的实现。
mark

这个值得考虑,http://www.iteye.com/topic/575052 --------------------编程问答--------------------
引用 11 楼 Yweige2010 的回复:
楼主不在吗?


我不是LZ 啊, 我只是也有这个疑问,不过解决了。
仔细看我的注释啊 --------------------编程问答-------------------- 还是不对啊 我没有加volatile 关键字 程序还是正常的结束了 

[C:\]java -server VolatileObj
Java HotSpot(TM) Client VM
stop My Thread 686437259
Main Thread false --------------------编程问答-------------------- 看到效果了 很不错 
补充:Java ,  Java EE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,