可以在java中将volatile变量定义为static吗?

时间:2011-03-27 19:34:08

标签: java multithreading concurrency

我可以声明这样的事吗??

static volatile boolean first=false;

5 个答案:

答案 0 :(得分:58)

扩展迈克尔的评论。

static仅表示与包含类的实例无关。

volatile只是意味着其他线程可能会在没有警告的情况下更改该值。

所以你的问题归结为“可以在没有警告的情况下由另一个线程更改与包含类的实例无关的字段吗?”

迈克尔指出,这个问题的答案是肯定的。实例关联与并发修改是正交的。

答案 1 :(得分:19)

是的,你可以。

Java中的static变量每个类存储一次(每个对象不存储一次,例如非静态变量)。这意味着所有对象(和静态方法)共享同一个变量。

将变量声明为volatile(无论是否static)表明该变量将被多个线程频繁访问。在Java中,这可以归结为指示线程无法缓存变量的值,但必须在变异后立即回写,以便其他线程看到更改。 (默认情况下,Java中的线程可以自由缓存变量。)

答案 2 :(得分:7)

不确定。两个修饰符的效果完全正交。

答案 3 :(得分:0)

是的,可以。

static boolean first=false;

声明静态变量时,无论创建多少个对象,所有对象都只有一个副本。 每个线程都有自己的缓存副本。

如果它是易失性的,线程应该每次都进入内存并获取变量的更新值。

static volatile boolean first=false;

它将

  

强制线程每次直接读取内存

首先找到变量的值。

答案 4 :(得分:0)

根据问题,可以,但是在那种情况下,我们需要处理所有情况。

通过多个线程访问静态值,每个线程可以拥有其本地缓存副本!为避免这种情况,您可以将变量声明为static volatile,这将强制线程在每次全局值时读取。但是,volatile不能代替适当的同步

private static volatile int cnt = 0;

private void checkCnt() {
     cnt+= 1;
     // some conditions
     // some code
     cnt -= 1;
}

同时执行checkCnt的次数多于cnt的最终值,与我们期望的值不同!为了解决该问题,我们必须实现锁以跟踪增量/减量

private static final Object lock = new Object();
private static volatile int cnt= 0;

private void checkCnt() {
     synchronized (lock) {
         cnt += 1;
     }
     //some conditions
     //some code
     synchronized (lock) {
         cnt -= 1;
     }
}

不确定这是正确的方法,但是通过此方法,我们可以管理事物并在volatile中使用static。 如果有更好的方法,请提供输入。