4

考虑以下代码:

class Foo {
    java.util.Timer timer = new java.util.Timer();

    void doAction() {
        ...
        timer.schedule(new SomeTimerTask(), 0L);
        ...
    }

    void cancelAction() {
        timer.cancel();
    }
}

从不同的线程调用方法。首先调用方法 doAction()。

我应该声明timer字段volatile对另一个线程可见吗?

4

5 回答 5

6

最好在方法上使用synchronized关键字,例如操纵实例变量的关键状态..doAction()cacelAction() timer

volatile关键字的作用与您描述的将 volatile 字段反映到每个线程的作用非常相似,但这仅适用于每个单独的操作,而不适用于所有操作。

于 2012-09-05T10:35:42.807 回答
3

您不需要使该字段易失,因为两个线程都不会更改该字段本身:它的值在初始化程序中设置一次,之后就不会改变。

您可能需要为您的方法添加同步,但volatile在这种情况下完全不需要声明变量:使用final会更合适。

于 2012-09-05T10:35:53.610 回答
2

Timer 类根据其javadoc是线程安全的,

因此,声明timervolatile就足够了。

但是,如果timer没有分配给其他任何地方(似乎是这种情况),更好的解决方案是将字段声明为final. 这足以确保timer可以从多个线程安全地使用该变量,而无需任何进一步的同步。(JLS 第 17.5 节特别保证了这一点。)

如果 Timer 不是线程安全的,那么您将需要在同步方法或块(或使用锁等实现的等效项)中对 Timer 实例执行所有操作。声明timervolatilefinal不会是足够的。

于 2012-09-05T10:41:26.503 回答
0

不需要将字段设为volatile但更好地使用synchronized方法。

public void synchronized doAction(){}

public void synchronized cancelAction(){}
于 2012-09-05T10:39:12.300 回答
0

即使没有将该字段声明为 volatile,它对所有线程都是可见的。与变量关联的volatile关键字将指示 java 运行时该变量可能会被多个线程修改,因此不应在本地缓存。

于 2012-09-05T10:35:51.060 回答