[concurrency-interest] Unsynchronized lazy conditions

Viktor Klang viktor.klang at gmail.com
Thu May 31 06:03:22 EDT 2018


Or leave the field un-volatile and introduce a release fence before the
logging call?

On Thu, May 31, 2018 at 11:58 AM, Alex Otenko <oleksandr.otenko at gmail.com>
wrote:

> The original requirement was it’s ok to sometimes log Warning several
> times. All this hacky atomicity is unnecessary. Just declare private
> volatile boolean warned, and leave the rest of the code as is.
>
> Alex
>
>
> On 31 May 2018, at 10:22, Viktor Klang via Concurrency-interest <
> concurrency-interest at cs.oswego.edu> wrote:
>
> Aleksey's suggestion(s) is/are definitely cleaner than mine:
>
> Depending on performance requirements the following might be cheaper,
> of course assuming you can type-wise hide the AtomicBoolean inheritance
> from consumer code:
>
> class Foo extends AtomicBoolean { // No indirection due to the allocation
> of AtomicBoolean
>    public void run() {
>      if (!get() && !getAndSet(true)) { // LOCK XCHG instead of LOCK CMPXCHG
>        LOG.warn("Warning");
>      }
>    }
> }
>
> On Thu, May 31, 2018 at 9:51 AM, Aleksey Shipilev via Concurrency-interest
> <concurrency-interest at cs.oswego.edu> wrote:
>
>> On 05/31/2018 07:07 AM, Shevek via Concurrency-interest wrote:
>> > Hi,
>> >
>> > I'd like to issue a warning message a relatively low number of times in
>> a multi-threaded
>> > application. My code is this:
>> >
>> > class Foo {
>> >   private boolean warned;
>> >
>> >   public void run() {
>> >     if (!warned) {
>> >        LOG.warn("Warning");
>> >        warned = true;
>> >     }
>> >   }
>> > }
>> >
>> > This is the only access to the variable 'warned', the value change is
>> deliberately unsynchronized,
>> > and monotonic. Am I right to believe that:
>> >
>> > * The first call WILL issue a warning.
>>
>> Yes.
>>
>> > * Any thread will issue the warning AT MOST once.
>>
>> Yes, I think so. It encroaches on darker corners of JMM, but it still
>> does what you want, methinks.
>>
>> > * Some (later) threads may not issue the warning, if the updated value
>> is flushed to the heap and
>> > they load it?
>>
>> Yes, except that "flushed to heap" part: that one is an implementation
>> detail.
>>
>>
>> > Is there a better way to do this without sacrificing performance? Is
>> this what the mysterious
>> > AtomicBoolean.lazySet, or even weakCompareAndSet is about?
>>
>> The classic way to do this is to do test and test-and-set:
>>
>> class Foo {
>>    private final AtomicBoolean warned;
>>
>>    public void run() {
>>      if (!warned.get() && warned.compareAndSet(false, true)) {
>>        LOG.warn("Warning");
>>      }
>>    }
>> }
>>
>> This gives you global only-once property, without sacrificing performance.
>>
>> There are options how do you represent "warned". I'd start with
>> AtomicBoolean, and then switched to
>> AtomicIntegerFieldUpdater over volatile field, or VarHandle if footprint
>> became a problem. With
>> VarHandles, you can even mix the modes: make the first "test" in plain
>> mode, and then do the CAS, if
>> first volatile check is too costly. But all of this is red herring until
>> there is a pressing need.
>> One-off guards are doable with just AtomicBoolean.
>>
>> -Aleksey
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>
>
> --
> Cheers,
>> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>


-- 
Cheers,
√
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180531/489e0ce3/attachment.html>


More information about the Concurrency-interest mailing list