【问题标题】:volatile keyword : Need explanation for this program behaviourvolatile 关键字:需要对此程序行为的解释
【发布时间】:2023-06-10 15:58:01
【问题描述】:

通过这个程序理解 volatile 关键字:

public class VolatileExample implements Runnable{    
private volatile int vol;
@Override
public void run(){
    vol=5;
    while(vol==5)
    {
        System.out.println("Inside run when vol is 5. Thread is : "+Thread.currentThread().getName());
            if("t2".equals(Thread.currentThread().getName()))
            {
                System.out.println("Got Thread : "+Thread.currentThread().getName()+" Now Calling Stop To End This Flow");
                stopIt();
            }
    }
}
public void stopIt(){
    vol=10;
}

public static void main(String[] args){
     VolatileExample ve1 = new VolatileExample();
     VolatileExample ve2 = new VolatileExample();

     Thread t1 = new Thread(ve1);
     Thread t2 = new Thread(ve1); //t1 and t2 operate on same instance of VolatileExample class  

     t1.setName("t1");
     t2.setName("t2");

     t1.start();
     t2.start();
 }
}

输出:

Inside run when vol is 5. Thread is : t1
Inside run when vol is 5. Thread is : t1
Inside run when vol is 5. Thread is : t2
Inside run when vol is 5. Thread is : t1
Got Thread : t2 Now Calling Stop To End This Flow
Inside run when vol is 5. Thread is : t1

所有对 vol 变量的写入都将立即写入主内存,并且应该立即对其他线程“可见”。 为什么调用 stopIt() 后 t1 线程仍然执行?看不到 vol 值现在是 10 而不是 5?

【问题讨论】:

  • 你为什么有ve2?你是想迷惑我们还是迷惑你自己?
  • 告白:我糊涂了!!!
  • 我之前使用 ve2 检查程序行为,但在本例中,我只使用 ve1

标签: java concurrency volatile


【解决方案1】:

没有证据表明t1stopIt() 被调用后运行。

事情可能会按照这个顺序发生

     t1                     t2
                         System.out.println("calling stopIt()");
while(vol==5)
System.out.println("Inside run")
                         enter stopIt()
                         vol = 10

这会给你你观察到的结果。 (还有其他可能的订购方式可以为您提供此结果。)

【讨论】:

  • stopIt()whileprintln 之间运行。
  • @shmosel 确切地说(这就是我所说的“其他订购可能性”:))
  • 明白了,所以这一切都归结为线程调度,我们“无法”预测输出,是吗?
  • 我试图在 vol=10 之后从 stopIt() 方法打印一些东西,即“stopIt called”,我有时看到“inside run t1”即使在“stopit called”被打印之后也会出现。不同运行的输出不同
  • @JyotsanaNandwani 检查 shmosel 的评论。在不同的运行中看到不同的输出是完全正常的。
最近更新 更多