使用volatile来使枚举线程安全

时间:2012-10-02 17:21:44

标签: java android

我有从网上下载一些文件的runnable,它看起来如下:

class Downloader implements Runnable {
    volatile Status status;
    public void run() {
       // ...
       while (status.isInProgress()) { ... }
    }
}

状态如下:

public enum Status {
    PAUSED {
        public int someData() { return 0; }
    },
    INPROGRESS {
        public int someData() { return 1; }
    }

    public abstract int someData();

    private String msg; 
    public String getSomeMsg() {
        return msg;
    }
    public void setSomeMsg(String s) {
        msg=s;
    }

    public boolean isInProgress() {
        return this == INPROGRESS;
    }
}

当用户按下暂停按钮时,状态变量从GUI线程设置为PAUSED。

代码是用java 1.6编译的,并且是为Android平台编译的。

我的问题是这样设置/读取Enum是否可以线程安全?我在这里读了很多文章:

http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html

并且我确信它是保存的,但它对枚举没有多少说明。

2 个答案:

答案 0 :(得分:4)

因此,对于this页面,可以将volatile与原语和对象(包括枚举)一起使用。此外,这是volatile关键字的典型用法,您可以看到here

注意:假设你的循环在完成后会中断(因为你没有定义DONE枚举值),最坏的情况是(i)用户暂停和(ii)下载在下一次迭代之前完成。在这种情况下,用户单击暂停,但会看到“下载完成”消息。

答案 1 :(得分:1)

我假设你有更多的一个线程从'status'读取值。如果是这样,代码将“保存”为volaile,以确保您的CPU在处理时始终具有“新鲜”值(它无法从缓存中读取)。但是这不会阻止任何变化或其他事情,我只会保证,如果某个线程查找该值,其他线程将读取该更改的值。