在枚举监视器上同步

时间:2012-10-10 18:02:27

标签: java monitor synchronized

我从1.5读到,我们可以使用enum for singleton

public enum Singleton {

  INSTANCE;

  //Singleton method
  public void someMethod( ) {...}
}

Singleton.INSTANCE.someMethod( );

这是否意味着枚举类型中的每个条目都是一个实例? 如果我用类定义枚举类型,我可以在枚举类型的每个条目上使用块同步吗?

class smokers extends Thread{

    public enum restype{
        TOBACCO,MATCH,PAPER 
    }

    public void run(){
        if(xxxx){

        synchronized(restype.PAPER){
                    ....
            }
        }
        else
        {
            synchronized(restype.MATCH){
                    ....
            }

        }
    }

这是有效的代码吗?

3 个答案:

答案 0 :(得分:1)

TOBACCO,MATCH,PAPER每个都是restype类型的实例。

您无法修改枚举常量,因此不需要同步。

如果要将它们用作对象锁,是的它是有效的。

注意:Java命名约定建议使用第一个字母作为类名的大写字母。

答案 1 :(得分:1)

您可以阅读Enums here。 由于它是一个常量且只有一个实例,因此您不需要同步。

但是如果要使用setter更改成员的值,则需要添加同步。

public enum Restype {
    TOBACCO(1), MATCH(2), PAPER(3);

    private int value = 0;//I have purposefully not declare it as final

    private Restype(int value) {
        this.setValue(value);
    }

    public void setValue(int value) {// now I can change value in multiple
                                        // threads.
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

现在,我将采用各种方式实现setValuegetValue的同步,最简单的方法是声明synchronized

但上面显然是滥用枚举。

在java中,您可以在任何对象上使用syncrhonized块,这样您就可以在枚举实例上同步块。

synchronized (Restype.TOBACCO) {
        // Allowed not recommenced 
        //every class should define its own mutex
    }

答案 2 :(得分:0)

代码看起来有效,但如果您需要这样做,请将逻辑放在枚举

public enum RestType{
    PAPER{
        public synchronized void foo(){ return true };
    },
    MATCH{
        public void foo(){ return false };
    };

    public abstract boolean foo(); //I've never see an abstract method define a 
                                   //synchronized method... so I have not 
                                   //idea if it's valid
}