我需要使同步的吸气剂使类线程安全吗?

时间:2019-05-14 20:59:35

标签: java multithreading

我已经编码:

class Counter {
    private int v;

    public synchronized int inc() {
        v = v + 1;
        return v;
    }

    public int get() {
        return v;
    }
}

为了性能起见,我需要最低限度&&(请不要使用并发包以及java.lang以外的其他包,我现在只想学习Java基础)

  1. 制作private volatile int v;
  2. 制作public int synchronized get() {...
  3. 一无所有(一切正常)

使线程上方的代码安全吗?

问题 Should getters and setters be synchronized? 由于模棱两可而没有给出答案:

  1.   

    一个常见的错误是假设需要使用同步   仅在写入共享变量时;这根本不是真的。

         

    对于每个可能被多个访问的可变状态变量   线程,对该变量的所有访问必须以相同的方式执行   锁住了。在这种情况下,我们说该变量受该变量保护   锁定。

  2.   

    通常,您不必对基元那么小心

所以对于原始int,我无法从中得出答案

2 个答案:

答案 0 :(得分:0)

如果您希望该类线程安全(并且我认为这包括避免脏读),则应选择第一个选项(将private volatile int v设为私有)。

第二个选项(公共int同步的get())也可以使用,但是同步更重(->性能降低)。

第三种选择(什么都不做(一切正常),可能会在其他线程中产生脏读。

更多信息:Java volatile keyword

答案 1 :(得分:0)

  
      
  • 在监视器上的一次解锁发生在该监视器上的每个后续锁定之前。
  •   
  • 在每次后续读取相同的volatile之前,都会对volatile字段进行写操作。
  •   

因此,如果getter线程不使用监视器(调用同步方法),则“在...之前发生”是没有意义的,因为它仅在后续获取监视器时才有意义。

因此,要么使getter和setter都同步,要么使字段可变(并且如果只有2个线程:setter和getter在这种情况下不需要同步setter,但是如果2个或更多setter-需要同步setter和也是易挥发的)

1个设置线程:

class Counter {
    private volatile int v; 

    public int inc() {
        v = v + 1;
        return v;
    }

    public int get() {
        return v;
    }
}

多个设置线程:

class Counter {
        private volatile int v; 

        public synchronized int inc() {
            v = v + 1;
            return v;
        }

        public int get() {
            return v;
        }
    }

对于两种情况都可以,但是很多余:

class Counter {
            private int v; // also can be volatile but redundant

            public synchronized int inc() {
                v = v + 1;
                return v;
            }

            public synchronized int get() {
                return v;
            }
        }