Unsynchronized lazy conditions

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
At the cost of about 500 bytes of class size, you could do the trick in Effective Java:

class Foo {
   private static class Logged {
     static void log() {}
 
      static {
         LOG.warn("Warning");       
      }
   }

   public void run() {
     Logged.log();
   }
}

On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest <[hidden email]> 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.
* Any thread will issue the warning AT MOST once.
* Some (later) threads may not issue the warning, if the updated value
is flushed to the heap and they load it?

Is there a better way to do this without sacrificing performance? Is
this what the mysterious AtomicBoolean.lazySet, or even
weakCompareAndSet is about?

This is right in the middle of something very concurrent which runs for
a long time, so reducing overhead is far more important than
occasionally issuing too many warnings.

Thank you.

S.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
I know there's a guarantee that the JVM _will_ call this when desired.
Is there also a guarantee that the JVM will _not_ call this i.e. there
is no spurious class or opportunistic initialization? I think that's
harder to promise.

On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:

> At the cost of about 500 bytes of class size, you could do the trick in
> Effective Java:
>
> class Foo {
>     private static class Logged {
>       static void log() {}
>        static {
> LOG.warn("Warning");
>        }
>     }
>
>     public void run() {
> Logged.log();
>     }
> }
>
> On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
> <[hidden email]
> <mailto:[hidden email]>> 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.
>     * Any thread will issue the warning AT MOST once.
>     * Some (later) threads may not issue the warning, if the updated value
>     is flushed to the heap and they load it?
>
>     Is there a better way to do this without sacrificing performance? Is
>     this what the mysterious AtomicBoolean.lazySet, or even
>     weakCompareAndSet is about?
>
>     This is right in the middle of something very concurrent which runs for
>     a long time, so reducing overhead is far more important than
>     occasionally issuing too many warnings.
>
>     Thank you.
>
>     S.
>     _______________________________________________
>     Concurrency-interest mailing list
>     [hidden email]
>     <mailto:[hidden email]>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
As I understand it, class loading is lazy and this will do the right thing.  It *may* get garbage collected if not referenced (and maybe log twice), but that can be worked around.  The pattern is very common for singletons.

On Thu, May 31, 2018 at 1:10 PM Shevek <[hidden email]> wrote:
I know there's a guarantee that the JVM _will_ call this when desired.
Is there also a guarantee that the JVM will _not_ call this i.e. there
is no spurious class or opportunistic initialization? I think that's
harder to promise.

On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:
> At the cost of about 500 bytes of class size, you could do the trick in
> Effective Java:
>
> class Foo {
>     private static class Logged {
>       static void log() {}
>        static {
> LOG.warn("Warning");
>        }
>     }
>
>     public void run() {
> Logged.log();
>     }
> }
>
> On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
> <[hidden email]
> <mailto:[hidden email]>> 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.
>     * Any thread will issue the warning AT MOST once.
>     * Some (later) threads may not issue the warning, if the updated value
>     is flushed to the heap and they load it?
>
>     Is there a better way to do this without sacrificing performance? Is
>     this what the mysterious AtomicBoolean.lazySet, or even
>     weakCompareAndSet is about?
>
>     This is right in the middle of something very concurrent which runs for
>     a long time, so reducing overhead is far more important than
>     occasionally issuing too many warnings.
>
>     Thank you.
>
>     S.
>     _______________________________________________
>     Concurrency-interest mailing list
>     [hidden email]
>     <mailto:[hidden email]>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
JLS 12.4.1 says: "A class or interface type T will be initialized immediately before the first occurrence of any one of the following."

They don't define "immediately," but I think it's reasonable to assume that it's more or less in line with people's intuition about lazy loading.

On Thu, May 31, 2018 at 4:16 PM, Carl Mastrangelo via Concurrency-interest <[hidden email]> wrote:
As I understand it, class loading is lazy and this will do the right thing.  It *may* get garbage collected if not referenced (and maybe log twice), but that can be worked around.  The pattern is very common for singletons.

On Thu, May 31, 2018 at 1:10 PM Shevek <[hidden email]> wrote:
I know there's a guarantee that the JVM _will_ call this when desired.
Is there also a guarantee that the JVM will _not_ call this i.e. there
is no spurious class or opportunistic initialization? I think that's
harder to promise.

On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:
> At the cost of about 500 bytes of class size, you could do the trick in
> Effective Java:
>
> class Foo {
>     private static class Logged {
>       static void log() {}
>        static {
> LOG.warn("Warning");
>        }
>     }
>
>     public void run() {
> Logged.log();
>     }
> }
>
> On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
> <[hidden email]
> <mailto:[hidden email]>> 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.
>     * Any thread will issue the warning AT MOST once.
>     * Some (later) threads may not issue the warning, if the updated value
>     is flushed to the heap and they load it?
>
>     Is there a better way to do this without sacrificing performance? Is
>     this what the mysterious AtomicBoolean.lazySet, or even
>     weakCompareAndSet is about?
>
>     This is right in the middle of something very concurrent which runs for
>     a long time, so reducing overhead is far more important than
>     occasionally issuing too many warnings.
>
>     Thank you.
>
>     S.
>     _______________________________________________
>     Concurrency-interest mailing list
>     [hidden email]
>     <mailto:[hidden email]>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
My question is the converse: It does NOT say "will not be initialized
UNLESS." That makes the Effective Java trick less useful for this case:
I don't mind more than one call to log() when at least one is allowed,
but if the guard condition never passes, I mustn't have spurious calls.

On 05/31/2018 02:42 PM, Yuval Shavit wrote:

> JLS 12.4.1 says: "A class or interface typeTwill be initialized
> immediately before the first occurrence of any one of the following."
>
> They don't define "immediately," but I think it's reasonable to assume
> that it's more or less in line with people's intuition about lazy loading.
>
> On Thu, May 31, 2018 at 4:16 PM, Carl Mastrangelo via
> Concurrency-interest <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     As I understand it, class loading is lazy and this will do the right
>     thing.  It *may* get garbage collected if not referenced (and maybe
>     log twice), but that can be worked around.  The pattern is very
>     common for singletons.
>
>     On Thu, May 31, 2018 at 1:10 PM Shevek <[hidden email]
>     <mailto:[hidden email]>> wrote:
>
>         I know there's a guarantee that the JVM _will_ call this when
>         desired.
>         Is there also a guarantee that the JVM will _not_ call this i.e.
>         there
>         is no spurious class or opportunistic initialization? I think
>         that's
>         harder to promise.
>
>         On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:
>          > At the cost of about 500 bytes of class size, you could do
>         the trick in
>          > Effective Java:
>          >
>          > class Foo {
>          >     private static class Logged {
>          >       static void log() {}
>          >        static {
>          > LOG.warn("Warning");
>          >        }
>          >     }
>          >
>          >     public void run() {
>          > Logged.log();
>          >     }
>          > }
>          >
>          > On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
>          > <[hidden email]
>         <mailto:[hidden email]>
>          > <mailto:[hidden email]
>         <mailto:[hidden email]>>> 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.
>          >     * Any thread will issue the warning AT MOST once.
>          >     * Some (later) threads may not issue the warning, if the
>         updated value
>          >     is flushed to the heap and they load it?
>          >
>          >     Is there a better way to do this without sacrificing
>         performance? Is
>          >     this what the mysterious AtomicBoolean.lazySet, or even
>          >     weakCompareAndSet is about?
>          >
>          >     This is right in the middle of something very concurrent
>         which runs for
>          >     a long time, so reducing overhead is far more important than
>          >     occasionally issuing too many warnings.
>          >
>          >     Thank you.
>          >
>          >     S.
>          >     _______________________________________________
>          >     Concurrency-interest mailing list
>          > [hidden email]
>         <mailto:[hidden email]>
>          >     <mailto:[hidden email]
>         <mailto:[hidden email]>>
>          > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>         <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>          >
>
>
>     _______________________________________________
>     Concurrency-interest mailing list
>     [hidden email]
>     <mailto:[hidden email]>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>     <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
That was the thing I was trying to indicate.  Because class initialization can have side effects, it would be unsafe for the JVM to eagerly load class files.  

On Thu, May 31, 2018 at 3:49 PM Shevek <[hidden email]> wrote:
My question is the converse: It does NOT say "will not be initialized
UNLESS." That makes the Effective Java trick less useful for this case:
I don't mind more than one call to log() when at least one is allowed,
but if the guard condition never passes, I mustn't have spurious calls.

On 05/31/2018 02:42 PM, Yuval Shavit wrote:
> JLS 12.4.1 says: "A class or interface typeTwill be initialized
> immediately before the first occurrence of any one of the following."
>
> They don't define "immediately," but I think it's reasonable to assume
> that it's more or less in line with people's intuition about lazy loading.
>
> On Thu, May 31, 2018 at 4:16 PM, Carl Mastrangelo via
> Concurrency-interest <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     As I understand it, class loading is lazy and this will do the right
>     thing.  It *may* get garbage collected if not referenced (and maybe
>     log twice), but that can be worked around.  The pattern is very
>     common for singletons.
>
>     On Thu, May 31, 2018 at 1:10 PM Shevek <[hidden email]
>     <mailto:[hidden email]>> wrote:
>
>         I know there's a guarantee that the JVM _will_ call this when
>         desired.
>         Is there also a guarantee that the JVM will _not_ call this i.e.
>         there
>         is no spurious class or opportunistic initialization? I think
>         that's
>         harder to promise.
>
>         On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:
>          > At the cost of about 500 bytes of class size, you could do
>         the trick in
>          > Effective Java:
>          >
>          > class Foo {
>          >     private static class Logged {
>          >       static void log() {}
>          >        static {
>          > LOG.warn("Warning");
>          >        }
>          >     }
>          >
>          >     public void run() {
>          > Logged.log();
>          >     }
>          > }
>          >
>          > On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
>          > <[hidden email]
>         <mailto:[hidden email]>
>          > <mailto:[hidden email]
>         <mailto:[hidden email]>>> 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.
>          >     * Any thread will issue the warning AT MOST once.
>          >     * Some (later) threads may not issue the warning, if the
>         updated value
>          >     is flushed to the heap and they load it?
>          >
>          >     Is there a better way to do this without sacrificing
>         performance? Is
>          >     this what the mysterious AtomicBoolean.lazySet, or even
>          >     weakCompareAndSet is about?
>          >
>          >     This is right in the middle of something very concurrent
>         which runs for
>          >     a long time, so reducing overhead is far more important than
>          >     occasionally issuing too many warnings.
>          >
>          >     Thank you.
>          >
>          >     S.
>          >     _______________________________________________
>          >     Concurrency-interest mailing list
>          > [hidden email]
>         <mailto:[hidden email]>
>          >     <mailto:[hidden email]
>         <mailto:[hidden email]>>
>          > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>         <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>          >
>
>
>     _______________________________________________
>     Concurrency-interest mailing list
>     [hidden email]
>     <mailto:[hidden email]>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>     <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
In reply to this post by JSR166 Concurrency mailing list
Classloading can be lazy or eager. Class initialization is very precise.

David

> -----Original Message-----
> From: Concurrency-interest <[hidden email]> On Behalf Of Shevek via Concurrency-interest
> Sent: Friday, June 1, 2018 8:49 AM
> To: Yuval Shavit <[hidden email]>; Carl Mastrangelo <[hidden email]>
> Cc: [hidden email]
> Subject: Re: [concurrency-interest] Unsynchronized lazy conditions
>
> My question is the converse: It does NOT say "will not be initialized UNLESS." That makes the Effective Java trick less useful for this
> case:
> I don't mind more than one call to log() when at least one is allowed, but if the guard condition never passes, I mustn't have spurious
> calls.
>
> On 05/31/2018 02:42 PM, Yuval Shavit wrote:
> > JLS 12.4.1 says: "A class or interface typeTwill be initialized
> > immediately before the first occurrence of any one of the following."
> >
> > They don't define "immediately," but I think it's reasonable to assume
> > that it's more or less in line with people's intuition about lazy loading.
> >
> > On Thu, May 31, 2018 at 4:16 PM, Carl Mastrangelo via
> > Concurrency-interest <[hidden email]
> > <mailto:[hidden email]>> wrote:
> >
> >     As I understand it, class loading is lazy and this will do the right
> >     thing.  It *may* get garbage collected if not referenced (and maybe
> >     log twice), but that can be worked around.  The pattern is very
> >     common for singletons.
> >
> >     On Thu, May 31, 2018 at 1:10 PM Shevek <[hidden email]
> >     <mailto:[hidden email]>> wrote:
> >
> >         I know there's a guarantee that the JVM _will_ call this when
> >         desired.
> >         Is there also a guarantee that the JVM will _not_ call this i.e.
> >         there
> >         is no spurious class or opportunistic initialization? I think
> >         that's
> >         harder to promise.
> >
> >         On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:
> >          > At the cost of about 500 bytes of class size, you could do
> >         the trick in
> >          > Effective Java:
> >          >
> >          > class Foo {
> >          >     private static class Logged {
> >          >       static void log() {}
> >          >        static {
> >          > LOG.warn("Warning");
> >          >        }
> >          >     }
> >          >
> >          >     public void run() {
> >          > Logged.log();
> >          >     }
> >          > }
> >          >
> >          > On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
> >          > <[hidden email]
> >         <mailto:[hidden email]>
> >          > <mailto:[hidden email]
> >         <mailto:[hidden email]>>> 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.
> >          >     * Any thread will issue the warning AT MOST once.
> >          >     * Some (later) threads may not issue the warning, if the
> >         updated value
> >          >     is flushed to the heap and they load it?
> >          >
> >          >     Is there a better way to do this without sacrificing
> >         performance? Is
> >          >     this what the mysterious AtomicBoolean.lazySet, or even
> >          >     weakCompareAndSet is about?
> >          >
> >          >     This is right in the middle of something very concurrent
> >         which runs for
> >          >     a long time, so reducing overhead is far more important than
> >          >     occasionally issuing too many warnings.
> >          >
> >          >     Thank you.
> >          >
> >          >     S.
> >          >     _______________________________________________
> >          >     Concurrency-interest mailing list
> >          > [hidden email]
> >         <mailto:[hidden email]>
> >          >     <mailto:[hidden email]
> >         <mailto:[hidden email]>>
> >          > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >         <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
> >          >
> >
> >
> >     _______________________________________________
> >     Concurrency-interest mailing list
> >     [hidden email]
> >     <mailto:[hidden email]>
> >     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >     <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
> >
> >
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
I think the key word is "immediately." If the initialization happened far before (ie, that converse case you mentioned), then it wouldn't be immediately before.

On Thu, May 31, 2018, 8:33 PM David Holmes <[hidden email]> wrote:
Classloading can be lazy or eager. Class initialization is very precise.

David

> -----Original Message-----
> From: Concurrency-interest <[hidden email]> On Behalf Of Shevek via Concurrency-interest
> Sent: Friday, June 1, 2018 8:49 AM
> To: Yuval Shavit <[hidden email]>; Carl Mastrangelo <[hidden email]>
> Cc: [hidden email]
> Subject: Re: [concurrency-interest] Unsynchronized lazy conditions
>
> My question is the converse: It does NOT say "will not be initialized UNLESS." That makes the Effective Java trick less useful for this
> case:
> I don't mind more than one call to log() when at least one is allowed, but if the guard condition never passes, I mustn't have spurious
> calls.
>
> On 05/31/2018 02:42 PM, Yuval Shavit wrote:
> > JLS 12.4.1 says: "A class or interface typeTwill be initialized
> > immediately before the first occurrence of any one of the following."
> >
> > They don't define "immediately," but I think it's reasonable to assume
> > that it's more or less in line with people's intuition about lazy loading.
> >
> > On Thu, May 31, 2018 at 4:16 PM, Carl Mastrangelo via
> > Concurrency-interest <[hidden email]
> > <mailto:[hidden email]>> wrote:
> >
> >     As I understand it, class loading is lazy and this will do the right
> >     thing.  It *may* get garbage collected if not referenced (and maybe
> >     log twice), but that can be worked around.  The pattern is very
> >     common for singletons.
> >
> >     On Thu, May 31, 2018 at 1:10 PM Shevek <[hidden email]
> >     <mailto:[hidden email]>> wrote:
> >
> >         I know there's a guarantee that the JVM _will_ call this when
> >         desired.
> >         Is there also a guarantee that the JVM will _not_ call this i.e.
> >         there
> >         is no spurious class or opportunistic initialization? I think
> >         that's
> >         harder to promise.
> >
> >         On 05/31/2018 01:06 PM, Carl Mastrangelo wrote:
> >          > At the cost of about 500 bytes of class size, you could do
> >         the trick in
> >          > Effective Java:
> >          >
> >          > class Foo {
> >          >     private static class Logged {
> >          >       static void log() {}
> >          >        static {
> >          > LOG.warn("Warning");
> >          >        }
> >          >     }
> >          >
> >          >     public void run() {
> >          > Logged.log();
> >          >     }
> >          > }
> >          >
> >          > On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest
> >          > <[hidden email]
> >         <mailto:[hidden email]>
> >          > <mailto:[hidden email]
> >         <mailto:[hidden email]>>> 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.
> >          >     * Any thread will issue the warning AT MOST once.
> >          >     * Some (later) threads may not issue the warning, if the
> >         updated value
> >          >     is flushed to the heap and they load it?
> >          >
> >          >     Is there a better way to do this without sacrificing
> >         performance? Is
> >          >     this what the mysterious AtomicBoolean.lazySet, or even
> >          >     weakCompareAndSet is about?
> >          >
> >          >     This is right in the middle of something very concurrent
> >         which runs for
> >          >     a long time, so reducing overhead is far more important than
> >          >     occasionally issuing too many warnings.
> >          >
> >          >     Thank you.
> >          >
> >          >     S.
> >          >     _______________________________________________
> >          >     Concurrency-interest mailing list
> >          > [hidden email]
> >         <mailto:[hidden email]>
> >          >     <mailto:[hidden email]
> >         <mailto:[hidden email]>>
> >          > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >         <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
> >          >
> >
> >
> >     _______________________________________________
> >     Concurrency-interest mailing list
> >     [hidden email]
> >     <mailto:[hidden email]>
> >     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >     <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
> >
> >
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
In reply to this post by JSR166 Concurrency mailing list
I would not call the trick Effective Java.


Alex

On 31 May 2018, at 21:06, Carl Mastrangelo via Concurrency-interest <[hidden email]> wrote:

At the cost of about 500 bytes of class size, you could do the trick in Effective Java:

class Foo {
   private static class Logged {
     static void log() {}
 
      static {
         LOG.warn("Warning");       
      }
   }

   public void run() {
     Logged.log();
   }
}

On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest <[hidden email]> 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.
* Any thread will issue the warning AT MOST once.
* Some (later) threads may not issue the warning, if the updated value
is flushed to the heap and they load it?

Is there a better way to do this without sacrificing performance? Is
this what the mysterious AtomicBoolean.lazySet, or even
weakCompareAndSet is about?

This is right in the middle of something very concurrent which runs for
a long time, so reducing overhead is far more important than
occasionally issuing too many warnings.

Thank you.

S.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
In reply to this post by JSR166 Concurrency mailing list
Agreed, I've got a class that's higly concurrent, trying to log anything
was problematic, because of the contention it caused.  Logging can cause
significant contention, expecially under stress, so you don't want to be
logging unnecessarily.

You know what the best solution was?  A single threaded Executor.  No
more contention due to logging.

static void log(Level level, String message, Object[] parameters,
Throwable thrown){
         final LogRecord record = new LogRecord(level, message);
         record.setParameters(parameters);
         record.setThrown(thrown);
     logExec.submit(new Runnable(){
         public void run() {
         logger.log(record);
         }
     });
     }

On 31/05/2018 7:58 PM, Alex Otenko via Concurrency-interest 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
>> <[hidden email]
>> <mailto:[hidden email]>> 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 <[hidden email]
>> <mailto:[hidden email]>> 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
>>     [hidden email]
>>     <mailto:[hidden email]>
>>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>     <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>>
>>
>>
>>
>> --
>> Cheers,
>> √
>> _______________________________________________
>> Concurrency-interest mailing list
>> [hidden email]
>> <mailto:[hidden email]>
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Unsynchronized lazy conditions

JSR166 Concurrency mailing list
In reply to this post by JSR166 Concurrency mailing list
Peter, and now you have contention on logExec.submit. Not to mention that logging frameworks like already provide asynchronous logging and Log4J2, for example, uses Disruptor (https://logging.apache.org/log4j/2.x/manual/async.html), which passes messages between threads faster than any bounded queue you will use in Executor.submit.

> Peter <
> Logging can cause 
> significant contention, expecially under stress, so you don't want to be 
> logging unnecessarily.
> 
> You know what the best solution was?  A single threaded Executor.  No 
> more contention due to logging.
> 
> static void log(Level level, String message, Object[] parameters, 
> Throwable thrown){
>          final LogRecord record = new LogRecord(level, message);
>          record.setParameters(parameters);
>          record.setThrown(thrown);
>      logExec.submit(new Runnable(){
>          public void run() {
>          logger.log(record);
>          }
>      });
>      }

Regards,
Valentin
LinkedIn   GitHub   YouTube

On 1 June 2018 at 10:00, <[hidden email]> wrote:
Send Concurrency-interest mailing list submissions to
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        http://cs.oswego.edu/mailman/listinfo/concurrency-interest
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Concurrency-interest digest..."


Today's Topics:

   1. Re: Unsynchronized lazy conditions (Alex Otenko)
   2. Re: Unsynchronized lazy conditions (Peter)


----------------------------------------------------------------------

Message: 1
Date: Fri, 1 Jun 2018 07:34:13 +0100
From: Alex Otenko <[hidden email]>
To: Carl Mastrangelo <[hidden email]>
Cc: [hidden email], [hidden email]
Subject: Re: [concurrency-interest] Unsynchronized lazy conditions
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="utf-8"

I would not call the trick Effective Java.


Alex

> On 31 May 2018, at 21:06, Carl Mastrangelo via Concurrency-interest <[hidden email]> wrote:
>
> At the cost of about 500 bytes of class size, you could do the trick in Effective Java:
>
> class Foo {
>    private static class Logged {
>      static void log() {}

>       static {
>          LOG.warn("Warning");       
>       }
>    }
>
>    public void run() {
>      Logged.log();
>    }
> }
>
> On Wed, May 30, 2018 at 10:17 PM Shevek via Concurrency-interest <[hidden email] <mailto:[hidden email]>> 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.
> * Any thread will issue the warning AT MOST once.
> * Some (later) threads may not issue the warning, if the updated value
> is flushed to the heap and they load it?
>
> Is there a better way to do this without sacrificing performance? Is
> this what the mysterious AtomicBoolean.lazySet, or even
> weakCompareAndSet is about?
>
> This is right in the middle of something very concurrent which runs for
> a long time, so reducing overhead is far more important than
> occasionally issuing too many warnings.
>
> Thank you.
>
> S.
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email] <mailto:[hidden email]>
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180601/ffc2d96e/attachment-0001.html>

------------------------------

Message: 2
Date: Fri, 01 Jun 2018 21:32:47 +1000
From: Peter <[hidden email]>
To: [hidden email]
Subject: Re: [concurrency-interest] Unsynchronized lazy conditions
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=UTF-8; format=flowed

Agreed, I've got a class that's higly concurrent, trying to log anything
was problematic, because of the contention it caused.  Logging can cause
significant contention, expecially under stress, so you don't want to be
logging unnecessarily.

You know what the best solution was?  A single threaded Executor.  No
more contention due to logging.

static void log(Level level, String message, Object[] parameters,
Throwable thrown){
         final LogRecord record = new LogRecord(level, message);
         record.setParameters(parameters);
         record.setThrown(thrown);
     logExec.submit(new Runnable(){
         public void run() {
         logger.log(record);
         }
     });
     }

On 31/05/2018 7:58 PM, Alex Otenko via Concurrency-interest 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
>> <[hidden email]
>> <mailto:[hidden email]>> 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 <[hidden email]
>> <mailto:[hidden email]>> 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
>>     [hidden email]
>>     <mailto:[hidden email]>
>>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>     <http://cs.oswego.edu/mailman/listinfo/concurrency-interest>
>>
>>
>>
>>
>> --
>> Cheers,
>> √
>> _______________________________________________
>> Concurrency-interest mailing list
>> [hidden email]
>> <mailto:[hidden email]>
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest



------------------------------

Subject: Digest Footer

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


------------------------------

End of Concurrency-interest Digest, Vol 161, Issue 1
****************************************************


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
12