Java同步计数器-那么get()呢? [英] Java synchronized counter - what about get()?

查看:88
本文介绍了Java同步计数器-那么get()呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,简单的x++不是原子操作,但实际上是读-增量-写操作.这就是为什么它应该被同步.但是get()呢?我已经阅读过它也应该同步,但是有人可以解释一下为什么吗?通过引入happens-before关系来避免内存一致性错误? 如果get()经常被多个线程调用并且该值很少更改,那该怎么办呢? synchronized get()不会减慢它们的速度吗?在这种情况下,还有其他方法可以实现同步(不使用AtomicInteger)吗? volatile关键字在这里可以正常工作吗?

It's known that simple x++ is not an atomic operation, but in fact is read-increment-write operation. That is why it should be synchronized. But what about get()? I have read it should be synchronized too, but could someone explain me why? To avoid memory consistency errors by introducing happens-before relationship? What about a situation when get() is called very often by multiple threads and the value is rarely changed. Isn't synchronized get() slowing them down? Are there any other ways to achieve synchronization in that scenario (not using AtomicInteger)? Would volatile keyword work here?

public class Counter {
    private int value;

    public synchronized int get() { return value; }
    public synchronized int increment() { return ++value; }
    public synchronized int decrement() { return --value; }
}

谢谢!

我想说清楚.通过使用volatile,我的意思是引入该关键字并在get()方法中删除synchronized.我想知道这是否将使其具有线程安全性,但是如果有许多线程正在读取该值并且很少更改该值,那么它是否也会更有效.

I would like to make myself clear. By using volatile I meant introducing that keyword and removing synchronized in get() method. I was wondering if it will make it thread-safe but also more efficient if many threads are reading the value and one is rarely changing it.

推荐答案

在这种情况下是否还有其他方法可以实现同步(不使用AtomicInteger)?

Are there any other ways to achieve synchronization in that scenario (not using AtomicInteger)?

首先,您应该使用

First off, you should be using AtomicInteger if you can. I'm not sure why you would not use it.

易失性关键字在这里可以工作吗?

Would volatile keyword work here?

是,但++除外. AtomicInteger提供安全的增量而不会锁定.如果您要自己滚动(出于某种疯狂的原因),则将需要阻塞或需要复制AtomicInteger内部自旋机制.

Yes except not for the ++. AtomicInteger provides a safe increment without locking. If you want to roll your own (for some crazy reason) then you will need the blocking or you need to duplicate the AtomicInteger internal spin mechanisms.

但是get()呢?我已经阅读过它也应该同步,但是有人可以解释一下为什么吗?

But what about get()? I have read it should be synchronized too, but could someone explain me why?

AtomicInteger包装volatile int以提供其功能.当您访问volatile字段时,也会越过get()上的内存屏障.您需要越过该内存障碍,以确保如果另一个线程更新了该值,则调用get()的线程将看到该更新.否则,线程可能正在使用过时的值.

AtomicInteger wraps a volatile int to provide its functionality. When you access the volatile field you cross a memory barrier on the get() as well. You need to cross that memory barrier to ensure that if another thread has updated the value, the thread calling the get() sees the update. Otherwise, a thread could be working with a outdated value.

这篇关于Java同步计数器-那么get()呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆