举个volatile例子 请举个例子, 不使用 volatile 关键字时, 结果是不稳定的,使用volatile时,结果是不稳定的不要说明, 只要一段简短的java代码来说明只有使用 volatile 关键字时才能达到预期的目标 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 public class Counter_ThreadSafe { public int getCount(){ return _count; } public synchronized void count(){ ++_count; } private volatile int _count=0;}////由此不同线程调用每次调用getCount() 都会得到正确计数值。////不过这个例子似乎不是很好。因为必须对count加synchronized 这个修饰符应该表示变量是线程安全的吧 你写两个或多个线程,并发访问同一个volatile的变量i 例如在run里面: if(i>0) { Thread,.sleep(10); System.out.println(i--); } 如果某个线程的输出为0甚至是负数,则说明你的程序不是线程安全的 但是加了volatile修饰应该就不会有这种情况发生 通过测试二楼的代码, 发现结果很不稳定, 与没有volatile修饰符结果是一样的,代码如下:import java.util.Random;public class Counter_ThreadSafe { public int getCount(){ return _count; } public synchronized void count(){ ++_count; } private volatile int _count=0; public static void main(String[] args) throws InterruptedException { final Counter_ThreadSafe c = new Counter_ThreadSafe(); final Random rand = new Random(); for (int i = 0; i < 100; i++) { Thread.sleep(0); new Thread(new Runnable() { public void run() { try { c.count(); Thread.sleep(rand.nextInt() % 2 + 2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(c.getCount()); } }).start(); } }}测试三楼的代码, 加不加volatile 都会有负数的情况发生, 代码如下:import java.util.Random;public class Counter_ThreadSafe { private static volatile int i = 7; private void count() throws InterruptedException { if(i>0) { Thread.sleep(10); System.out.println(i--); } } public static void main(String[] args) throws InterruptedException { final Counter_ThreadSafe c = new Counter_ThreadSafe(); final Random rand = new Random(); for (int i = 0; i < 100; i++) { Thread.sleep(0); new Thread(new Runnable() { public void run() { try { c.count(); Thread.sleep(rand.nextInt() % 2 + 2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //System.out.println(c.getCount()); } }).start(); } }} 请举个例子, 不使用 volatile 关键字时, 结果是不稳定的,使用volatile时,结果是稳定的 使用volatile时,结果是稳定的, 发贴时写成不稳定了, 不好意思, ```当时太急了`` 只接触过一次,是在学习线程安全的Singleton模式的时候学的 楼主的样例代码犯了与3楼朋友同一个毛病。我把三楼的代码再贴一下:if(i>0) { Thread,.sleep(10); System.out.println(i--); } 这里很明显无法表现出volatile的功效。因为比如说当前i为1,i>0成立,那么接下去操作。碰到sleep()之后切换线程,i的值很有后可能被其它线程修改,这很正常。我想说的是,在Java中,volatile很难测试。因为在C/C++中测也不是很容易,还要设置编译选项,开启代码优化才可能发现volatile的功效。volatile字面意思是“不稳定的,易挥发的”。也就是说其值将受到外部的改变。在C/C++中,由于使用机器的寄存器,所以变量的值将会保存在寄存器中,比如以下代码:while(i > 0){ i--;}i的值很有可能被放入寄存器(这里也很有可能被放在循环计数寄存器中),这样在这个循环中,i 所在地址的内容可能不会一下子受到改变,改变的只是寄存器中的值。如果给他加以volatile修饰的话,那么每次做“i--”的时候,总要访问i 的地址,对于内容进行减1操作(尽管这可能会在Cache中)。不过即使是访问Cache,其速度也不会有寄存器那么快。所以,在目前Java环境下测volatile比较困难,目前的环境也没有提供非常完善的代码调试工具,也就是说不公开Java虚拟机指令集。至少在Eclipse上没有,不知道在NetBeans上怎么样。不过即使要发挥volatile,那么也只能依靠JIT技术了。让Java字节码及时地转为本地机器指令码进行运行,只有这样才有可能看到效果,而且转换后的机器二进制码又要是经过一定优化的,也就是不用volatile修饰的变量尽可能的使用寄存器。所以楼主也不要怪二楼、三楼,先不看你的测试代码,本身的测试环境也是有限的。 关于try catch finally,请详解 FileWriter的flush方法 关于new 源文件编译成jar包的问题 进来给个意见吧.谢谢..~ 数据库驱动的开发~~ java 对oracle 表监控问题 利用java如何探测位于局域网内的电脑的ip地址? 问题在哪里? Java能干什么?初级问题 请问各位大侠一个问题,我原来是做c的,要参加一个java笔试 mfc 同一个对话框内, 编辑框 不响应 按钮的文本输入消息
public int getCount(){
return _count;
}
public synchronized void count(){
++_count;
}
private volatile int _count=0;
}////由此不同线程调用每次调用getCount() 都会得到正确计数值。
////不过这个例子似乎不是很好。因为必须对count加synchronized
你写两个或多个线程,并发访问同一个volatile的变量i
例如在run里面:
if(i>0)
{
Thread,.sleep(10);
System.out.println(i--);
}
如果某个线程的输出为0甚至是负数,则说明你的程序不是线程安全的
但是加了volatile修饰应该就不会有这种情况发生
return _count;
}
public synchronized void count(){
++_count;
}
private volatile int _count=0; public static void main(String[] args) throws InterruptedException {
final Counter_ThreadSafe c = new Counter_ThreadSafe();
final Random rand = new Random();
for (int i = 0; i < 100; i++) {
Thread.sleep(0);
new Thread(new Runnable() {
public void run() {
try {
c.count();
Thread.sleep(rand.nextInt() % 2 + 2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(c.getCount());
}
}).start();
}
}
}测试三楼的代码, 加不加volatile 都会有负数的情况发生, 代码如下:import java.util.Random;public class Counter_ThreadSafe { private static volatile int i = 7; private void count() throws InterruptedException {
if(i>0)
{
Thread.sleep(10);
System.out.println(i--);
}
} public static void main(String[] args) throws InterruptedException {
final Counter_ThreadSafe c = new Counter_ThreadSafe();
final Random rand = new Random();
for (int i = 0; i < 100; i++) {
Thread.sleep(0);
new Thread(new Runnable() {
public void run() {
try {
c.count();
Thread.sleep(rand.nextInt() % 2 + 2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(c.getCount());
}
}).start();
}
}
}
我把三楼的代码再贴一下:if(i>0)
{
Thread,.sleep(10);
System.out.println(i--);
}
这里很明显无法表现出volatile的功效。因为比如说当前i为1,i>0成立,那么接下去操作。碰到sleep()之后切换线程,i的值很有后可能被其它线程修改,这很正常。我想说的是,在Java中,volatile很难测试。因为在C/C++中测也不是很容易,还要设置编译选项,开启代码优化才可能发现volatile的功效。
volatile字面意思是“不稳定的,易挥发的”。也就是说其值将受到外部的改变。在C/C++中,由于使用机器的寄存器,所以变量的值将会保存在寄存器中,比如以下代码:while(i > 0)
{
i--;
}i的值很有可能被放入寄存器(这里也很有可能被放在循环计数寄存器中),这样在这个循环中,i 所在地址的内容可能不会一下子受到改变,改变的只是寄存器中的值。如果给他加以volatile修饰的话,那么每次做“i--”的时候,总要访问i 的地址,对于内容进行减1操作(尽管这可能会在Cache中)。不过即使是访问Cache,其速度也不会有寄存器那么快。
所以,在目前Java环境下测volatile比较困难,目前的环境也没有提供非常完善的代码调试工具,也就是说不公开Java虚拟机指令集。至少在Eclipse上没有,不知道在NetBeans上怎么样。不过即使要发挥volatile,那么也只能依靠JIT技术了。让Java字节码及时地转为本地机器指令码进行运行,只有这样才有可能看到效果,而且转换后的机器二进制码又要是经过一定优化的,也就是不用volatile修饰的变量尽可能的使用寄存器。
所以楼主也不要怪二楼、三楼,先不看你的测试代码,本身的测试环境也是有限的。