无法模拟使用volatile字段修饰符

时间:2012-03-06 04:50:59

标签: java multithreading

在下面的例子中

    private Integer a = 10;
    private Integer c = -10;
    private int b = -10;

    public void acquire(){
        synchronized(a){
            print("acquire()");
            try{                    
                b = -12;
                //Thread.sleep(5000);
                a.wait(5000);
                print("acquire : "+b);
                print("I have awoken");
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        print("Leaving acquire()");
    }


    public void modify(int n){
        print("Entered in modfy");
        synchronized(a){
            try{                    
                b = -15;
                //a.wait(5000);
                Thread.sleep(5000);
                print("modfy : "+b);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

线程A正在调用acquire(),线程B正在调用modify()。

另一个线程可以看到一个线程更改的b值。

  1. 线程A:b = -12;
  2. 线程B:b = -15;打印b;出口
  3. 线程A:打印b的新值,即-15。
  4. 我如何使用上面的示例模拟需要挥发性,然后在上面的示例中使用volatile

3 个答案:

答案 0 :(得分:1)

如果您只是想模拟volatile的需要,只需执行此操作:

volatile int x = 10;
public void acquire()
{
     x = 15;   
     print("acquire()");
}

public void modify(int n)
{
     print("Entered in modfy");
     x = -15;
}

//Let threadA call acquire() and threadB call modify()Then print x and see (there should not be any race conditions)

如果您想让它变得更有趣,请添加更多主题和方法并尝试访问x

答案 1 :(得分:0)

我在这里有一个例子

http://vanillajava.blogspot.com/2012/01/demonstrating-when-volatile-is-required.html

您可能会遇到的问题是;

  • 虽然volatile提供了一些内存一致性保证,但不使用volatile 保证您会看到问题。
  • 在代码经过优化之后,即在运行10,000次之后,Sun / Oracle / OpenJDK JVM中似乎不会出现此问题。
  • 通常会涉及微妙的竞争条件,即使是微小的事情也可能意味着你没有发现问题。

答案 2 :(得分:0)

根据“实践中的并发 - 书”,volatile只能用于标志类型的变量(它们是布尔值)。 在新状态不依赖于变量的旧状态的情况下应该使用Volatile。

volatile boolean flag = true;

while(flag){ ..//某事;

}

当其他线程可以修改flag变量时,将通知原始线程,因为该标志被标记为volatile。否则,循环可能永远存在。