CDI PostConstruct and volatile fields









up vote
2
down vote

favorite
1












Using a post construct approach when we want to conditionally initialise some of the bean's fields, do we need to care about volatility of the field, since it is a multithread environment?



Say, we have something like this:



@ApplicationScoped
public class FooService

private final ConfigurationService configurationService;

private FooBean fooBean;

@Inject
FooService(ConfigurationService configurationService)
this.configurationService = configurationService;


void init(@Observes @Initialized(ApplicationScoped.class) Object ignored)
if (configurationService.isFooBeanInitialisationEnabled())
fooBean = initialiseFooBean(configurationService); // some initialisation



void cleanup(@Observes @Destroyed(ApplicationScoped.class) Object ignored)
if (fooBean != null)
fooBean.cleanup();





So should the fooBean be wrapped into, let's say, the AtomicReference or be a volatile or it would be a redundant extra protection?



P.S. In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not? However I would like to have an answer for a more general case.










share|improve this question



























    up vote
    2
    down vote

    favorite
    1












    Using a post construct approach when we want to conditionally initialise some of the bean's fields, do we need to care about volatility of the field, since it is a multithread environment?



    Say, we have something like this:



    @ApplicationScoped
    public class FooService

    private final ConfigurationService configurationService;

    private FooBean fooBean;

    @Inject
    FooService(ConfigurationService configurationService)
    this.configurationService = configurationService;


    void init(@Observes @Initialized(ApplicationScoped.class) Object ignored)
    if (configurationService.isFooBeanInitialisationEnabled())
    fooBean = initialiseFooBean(configurationService); // some initialisation



    void cleanup(@Observes @Destroyed(ApplicationScoped.class) Object ignored)
    if (fooBean != null)
    fooBean.cleanup();





    So should the fooBean be wrapped into, let's say, the AtomicReference or be a volatile or it would be a redundant extra protection?



    P.S. In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not? However I would like to have an answer for a more general case.










    share|improve this question

























      up vote
      2
      down vote

      favorite
      1









      up vote
      2
      down vote

      favorite
      1






      1





      Using a post construct approach when we want to conditionally initialise some of the bean's fields, do we need to care about volatility of the field, since it is a multithread environment?



      Say, we have something like this:



      @ApplicationScoped
      public class FooService

      private final ConfigurationService configurationService;

      private FooBean fooBean;

      @Inject
      FooService(ConfigurationService configurationService)
      this.configurationService = configurationService;


      void init(@Observes @Initialized(ApplicationScoped.class) Object ignored)
      if (configurationService.isFooBeanInitialisationEnabled())
      fooBean = initialiseFooBean(configurationService); // some initialisation



      void cleanup(@Observes @Destroyed(ApplicationScoped.class) Object ignored)
      if (fooBean != null)
      fooBean.cleanup();





      So should the fooBean be wrapped into, let's say, the AtomicReference or be a volatile or it would be a redundant extra protection?



      P.S. In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not? However I would like to have an answer for a more general case.










      share|improve this question















      Using a post construct approach when we want to conditionally initialise some of the bean's fields, do we need to care about volatility of the field, since it is a multithread environment?



      Say, we have something like this:



      @ApplicationScoped
      public class FooService

      private final ConfigurationService configurationService;

      private FooBean fooBean;

      @Inject
      FooService(ConfigurationService configurationService)
      this.configurationService = configurationService;


      void init(@Observes @Initialized(ApplicationScoped.class) Object ignored)
      if (configurationService.isFooBeanInitialisationEnabled())
      fooBean = initialiseFooBean(configurationService); // some initialisation



      void cleanup(@Observes @Destroyed(ApplicationScoped.class) Object ignored)
      if (fooBean != null)
      fooBean.cleanup();





      So should the fooBean be wrapped into, let's say, the AtomicReference or be a volatile or it would be a redundant extra protection?



      P.S. In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not? However I would like to have an answer for a more general case.







      java java-ee concurrency cdi volatile






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 9 at 14:42

























      asked Nov 9 at 14:26









      Andremoniy

      21.6k672153




      21.6k672153






















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          I would say it depends which thread is actually initiating and destroying the contexts.
          If you use regular events, they are synchronous (asynchronous events have been added in CDI 2.0 with ObservesAsync, see
          Java EE 8: Sending asynchronous CDI 2.0 events with ManagedExecutorService ) so they are called in the same thread as the caller.



          In general, I don't think the same thread is used (in application servers or standalone applications) so I would recommend using volatile to ensure the right value is seen (basically the value constructed seen on destroy thread). However, it is not a use case happening so much to initiate and destroy your application in a concurrent way...






          share|improve this answer



























            up vote
            2
            down vote













            FooService is a singleton which is shared between all managed beans in the application.



            Annotation Type ApplicationScoped



            private FooBean fooBean is a state of the singleton object.



            By default, CDI does not manage concurrency so it is the responsibility of a developer.




            In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not?




            CDI specification does not restrict containers to use the same thread for initialization and destruction of the application context. This behavior is implementation specific. In general case those threads will be different because initialization happens on the thread handling the first request to the application but destruction happens on the thread handling request from management console.






            share|improve this answer




















            • do you have by anychange the part of the specification speaking about thread management?
              – Nicolas Henneaux
              Nov 9 at 15:30










            • This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
              – Illya Kysil
              Nov 9 at 23:25

















            up vote
            1
            down vote













            You may delegate concurrency management to EJB container - if your runtime environment includes one.



            Neither volatile nor AtomicReference are needed in this case!



            Following definition will do the job:



            @javax.ejb.Startup // initialize on application start
            @javax.ejb.Singleton // EJB Singleton
            public class FooService

            private final ConfigurationService configurationService;

            private FooBean fooBean;

            @javax.inject.Inject
            FooService(ConfigurationService configurationService)
            this.configurationService = configurationService;



            @javax.annotation.PostConstruct
            void init()
            if (configurationService.isFooBeanInitialisationEnabled())
            fooBean = initialiseFooBean(configurationService); // some initialisation



            @javax.annotation.PreDestroy
            void cleanup()
            if (fooBean != null)
            fooBean.cleanup();








            share|improve this answer



























              up vote
              1
              down vote













              According to the specification:




              An event with qualifier @Initialized(ApplicationScoped.class) is synchronously fired when the application context is initialized.



              An event with qualifier @BeforeDestroyed(ApplicationScoped.class) is synchronously fired when the application context is about to be destroyed, i.e. before the actual destruction.



              An event with qualifier @Destroyed(ApplicationScoped.class) is synchronously fired when the application context is destroyed, i.e. after the actual destruction.




              And according to this presentation Bean manager lifecycle: the lifecycle of the bean manager is synchronous between the different states of the process and the sequence is kept: "destroy not before init".



              Jboss are the specification lead of CDI 2.0



              I do not see any scenario that would require a volatile/protection. Even if T1 inits then T2 destroys, it will be T1 then T2, not T1 and T2 concurrently.



              And even if it would be concurrently, to have an issue it would imply weird scenario, edge scenario outside the CDI runtime:



              • T2 calls destroy (fooBean is null and now 'cached' in a register)

              • Then T1 calls init: destroy before init, at this point we are in the 4th dimension of CDI),

              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).

              Or



              • T2 calls a method that access fooBean (fooBean is null and now 'cached' in a register)

              • Then T1 calls init: T1 is initialized whereas fooBean has already been used by T2, at this point we are in the 4th dimension of CDI

              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).





              share|improve this answer


















              • 1




                thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                – Nicolas Henneaux
                Nov 12 at 13:57











              • it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                – Nicolas Labrot
                Nov 12 at 14:19










              • First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                – Nicolas Henneaux
                Nov 12 at 15:34







              • 1




                init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                – Nicolas Labrot
                Nov 12 at 16:07











              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "1"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53227585%2fcdi-postconstruct-and-volatile-fields%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              2
              down vote



              accepted










              I would say it depends which thread is actually initiating and destroying the contexts.
              If you use regular events, they are synchronous (asynchronous events have been added in CDI 2.0 with ObservesAsync, see
              Java EE 8: Sending asynchronous CDI 2.0 events with ManagedExecutorService ) so they are called in the same thread as the caller.



              In general, I don't think the same thread is used (in application servers or standalone applications) so I would recommend using volatile to ensure the right value is seen (basically the value constructed seen on destroy thread). However, it is not a use case happening so much to initiate and destroy your application in a concurrent way...






              share|improve this answer
























                up vote
                2
                down vote



                accepted










                I would say it depends which thread is actually initiating and destroying the contexts.
                If you use regular events, they are synchronous (asynchronous events have been added in CDI 2.0 with ObservesAsync, see
                Java EE 8: Sending asynchronous CDI 2.0 events with ManagedExecutorService ) so they are called in the same thread as the caller.



                In general, I don't think the same thread is used (in application servers or standalone applications) so I would recommend using volatile to ensure the right value is seen (basically the value constructed seen on destroy thread). However, it is not a use case happening so much to initiate and destroy your application in a concurrent way...






                share|improve this answer






















                  up vote
                  2
                  down vote



                  accepted







                  up vote
                  2
                  down vote



                  accepted






                  I would say it depends which thread is actually initiating and destroying the contexts.
                  If you use regular events, they are synchronous (asynchronous events have been added in CDI 2.0 with ObservesAsync, see
                  Java EE 8: Sending asynchronous CDI 2.0 events with ManagedExecutorService ) so they are called in the same thread as the caller.



                  In general, I don't think the same thread is used (in application servers or standalone applications) so I would recommend using volatile to ensure the right value is seen (basically the value constructed seen on destroy thread). However, it is not a use case happening so much to initiate and destroy your application in a concurrent way...






                  share|improve this answer












                  I would say it depends which thread is actually initiating and destroying the contexts.
                  If you use regular events, they are synchronous (asynchronous events have been added in CDI 2.0 with ObservesAsync, see
                  Java EE 8: Sending asynchronous CDI 2.0 events with ManagedExecutorService ) so they are called in the same thread as the caller.



                  In general, I don't think the same thread is used (in application servers or standalone applications) so I would recommend using volatile to ensure the right value is seen (basically the value constructed seen on destroy thread). However, it is not a use case happening so much to initiate and destroy your application in a concurrent way...







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 9 at 14:53









                  Nicolas Henneaux

                  5,13442647




                  5,13442647






















                      up vote
                      2
                      down vote













                      FooService is a singleton which is shared between all managed beans in the application.



                      Annotation Type ApplicationScoped



                      private FooBean fooBean is a state of the singleton object.



                      By default, CDI does not manage concurrency so it is the responsibility of a developer.




                      In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not?




                      CDI specification does not restrict containers to use the same thread for initialization and destruction of the application context. This behavior is implementation specific. In general case those threads will be different because initialization happens on the thread handling the first request to the application but destruction happens on the thread handling request from management console.






                      share|improve this answer




















                      • do you have by anychange the part of the specification speaking about thread management?
                        – Nicolas Henneaux
                        Nov 9 at 15:30










                      • This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
                        – Illya Kysil
                        Nov 9 at 23:25














                      up vote
                      2
                      down vote













                      FooService is a singleton which is shared between all managed beans in the application.



                      Annotation Type ApplicationScoped



                      private FooBean fooBean is a state of the singleton object.



                      By default, CDI does not manage concurrency so it is the responsibility of a developer.




                      In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not?




                      CDI specification does not restrict containers to use the same thread for initialization and destruction of the application context. This behavior is implementation specific. In general case those threads will be different because initialization happens on the thread handling the first request to the application but destruction happens on the thread handling request from management console.






                      share|improve this answer




















                      • do you have by anychange the part of the specification speaking about thread management?
                        – Nicolas Henneaux
                        Nov 9 at 15:30










                      • This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
                        – Illya Kysil
                        Nov 9 at 23:25












                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      FooService is a singleton which is shared between all managed beans in the application.



                      Annotation Type ApplicationScoped



                      private FooBean fooBean is a state of the singleton object.



                      By default, CDI does not manage concurrency so it is the responsibility of a developer.




                      In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not?




                      CDI specification does not restrict containers to use the same thread for initialization and destruction of the application context. This behavior is implementation specific. In general case those threads will be different because initialization happens on the thread handling the first request to the application but destruction happens on the thread handling request from management console.






                      share|improve this answer












                      FooService is a singleton which is shared between all managed beans in the application.



                      Annotation Type ApplicationScoped



                      private FooBean fooBean is a state of the singleton object.



                      By default, CDI does not manage concurrency so it is the responsibility of a developer.




                      In this particular case it can be reformulated as: are post construct and post destroy events performed by the same thread or not?




                      CDI specification does not restrict containers to use the same thread for initialization and destruction of the application context. This behavior is implementation specific. In general case those threads will be different because initialization happens on the thread handling the first request to the application but destruction happens on the thread handling request from management console.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 9 at 15:21









                      Illya Kysil

                      48425




                      48425











                      • do you have by anychange the part of the specification speaking about thread management?
                        – Nicolas Henneaux
                        Nov 9 at 15:30










                      • This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
                        – Illya Kysil
                        Nov 9 at 23:25
















                      • do you have by anychange the part of the specification speaking about thread management?
                        – Nicolas Henneaux
                        Nov 9 at 15:30










                      • This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
                        – Illya Kysil
                        Nov 9 at 23:25















                      do you have by anychange the part of the specification speaking about thread management?
                      – Nicolas Henneaux
                      Nov 9 at 15:30




                      do you have by anychange the part of the specification speaking about thread management?
                      – Nicolas Henneaux
                      Nov 9 at 15:30












                      This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
                      – Illya Kysil
                      Nov 9 at 23:25




                      This post by Stephan Knitelius summarizes the situation with concurrency management in CDI specification and provides guidance on how to replicate EJB concurrency mechanisms with CDI interceptors.
                      – Illya Kysil
                      Nov 9 at 23:25










                      up vote
                      1
                      down vote













                      You may delegate concurrency management to EJB container - if your runtime environment includes one.



                      Neither volatile nor AtomicReference are needed in this case!



                      Following definition will do the job:



                      @javax.ejb.Startup // initialize on application start
                      @javax.ejb.Singleton // EJB Singleton
                      public class FooService

                      private final ConfigurationService configurationService;

                      private FooBean fooBean;

                      @javax.inject.Inject
                      FooService(ConfigurationService configurationService)
                      this.configurationService = configurationService;



                      @javax.annotation.PostConstruct
                      void init()
                      if (configurationService.isFooBeanInitialisationEnabled())
                      fooBean = initialiseFooBean(configurationService); // some initialisation



                      @javax.annotation.PreDestroy
                      void cleanup()
                      if (fooBean != null)
                      fooBean.cleanup();








                      share|improve this answer
























                        up vote
                        1
                        down vote













                        You may delegate concurrency management to EJB container - if your runtime environment includes one.



                        Neither volatile nor AtomicReference are needed in this case!



                        Following definition will do the job:



                        @javax.ejb.Startup // initialize on application start
                        @javax.ejb.Singleton // EJB Singleton
                        public class FooService

                        private final ConfigurationService configurationService;

                        private FooBean fooBean;

                        @javax.inject.Inject
                        FooService(ConfigurationService configurationService)
                        this.configurationService = configurationService;



                        @javax.annotation.PostConstruct
                        void init()
                        if (configurationService.isFooBeanInitialisationEnabled())
                        fooBean = initialiseFooBean(configurationService); // some initialisation



                        @javax.annotation.PreDestroy
                        void cleanup()
                        if (fooBean != null)
                        fooBean.cleanup();








                        share|improve this answer






















                          up vote
                          1
                          down vote










                          up vote
                          1
                          down vote









                          You may delegate concurrency management to EJB container - if your runtime environment includes one.



                          Neither volatile nor AtomicReference are needed in this case!



                          Following definition will do the job:



                          @javax.ejb.Startup // initialize on application start
                          @javax.ejb.Singleton // EJB Singleton
                          public class FooService

                          private final ConfigurationService configurationService;

                          private FooBean fooBean;

                          @javax.inject.Inject
                          FooService(ConfigurationService configurationService)
                          this.configurationService = configurationService;



                          @javax.annotation.PostConstruct
                          void init()
                          if (configurationService.isFooBeanInitialisationEnabled())
                          fooBean = initialiseFooBean(configurationService); // some initialisation



                          @javax.annotation.PreDestroy
                          void cleanup()
                          if (fooBean != null)
                          fooBean.cleanup();








                          share|improve this answer












                          You may delegate concurrency management to EJB container - if your runtime environment includes one.



                          Neither volatile nor AtomicReference are needed in this case!



                          Following definition will do the job:



                          @javax.ejb.Startup // initialize on application start
                          @javax.ejb.Singleton // EJB Singleton
                          public class FooService

                          private final ConfigurationService configurationService;

                          private FooBean fooBean;

                          @javax.inject.Inject
                          FooService(ConfigurationService configurationService)
                          this.configurationService = configurationService;



                          @javax.annotation.PostConstruct
                          void init()
                          if (configurationService.isFooBeanInitialisationEnabled())
                          fooBean = initialiseFooBean(configurationService); // some initialisation



                          @javax.annotation.PreDestroy
                          void cleanup()
                          if (fooBean != null)
                          fooBean.cleanup();









                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 9 at 23:37









                          Illya Kysil

                          48425




                          48425




















                              up vote
                              1
                              down vote













                              According to the specification:




                              An event with qualifier @Initialized(ApplicationScoped.class) is synchronously fired when the application context is initialized.



                              An event with qualifier @BeforeDestroyed(ApplicationScoped.class) is synchronously fired when the application context is about to be destroyed, i.e. before the actual destruction.



                              An event with qualifier @Destroyed(ApplicationScoped.class) is synchronously fired when the application context is destroyed, i.e. after the actual destruction.




                              And according to this presentation Bean manager lifecycle: the lifecycle of the bean manager is synchronous between the different states of the process and the sequence is kept: "destroy not before init".



                              Jboss are the specification lead of CDI 2.0



                              I do not see any scenario that would require a volatile/protection. Even if T1 inits then T2 destroys, it will be T1 then T2, not T1 and T2 concurrently.



                              And even if it would be concurrently, to have an issue it would imply weird scenario, edge scenario outside the CDI runtime:



                              • T2 calls destroy (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: destroy before init, at this point we are in the 4th dimension of CDI),

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).

                              Or



                              • T2 calls a method that access fooBean (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: T1 is initialized whereas fooBean has already been used by T2, at this point we are in the 4th dimension of CDI

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).





                              share|improve this answer


















                              • 1




                                thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                                – Nicolas Henneaux
                                Nov 12 at 13:57











                              • it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                                – Nicolas Labrot
                                Nov 12 at 14:19










                              • First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                                – Nicolas Henneaux
                                Nov 12 at 15:34







                              • 1




                                init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                                – Nicolas Labrot
                                Nov 12 at 16:07















                              up vote
                              1
                              down vote













                              According to the specification:




                              An event with qualifier @Initialized(ApplicationScoped.class) is synchronously fired when the application context is initialized.



                              An event with qualifier @BeforeDestroyed(ApplicationScoped.class) is synchronously fired when the application context is about to be destroyed, i.e. before the actual destruction.



                              An event with qualifier @Destroyed(ApplicationScoped.class) is synchronously fired when the application context is destroyed, i.e. after the actual destruction.




                              And according to this presentation Bean manager lifecycle: the lifecycle of the bean manager is synchronous between the different states of the process and the sequence is kept: "destroy not before init".



                              Jboss are the specification lead of CDI 2.0



                              I do not see any scenario that would require a volatile/protection. Even if T1 inits then T2 destroys, it will be T1 then T2, not T1 and T2 concurrently.



                              And even if it would be concurrently, to have an issue it would imply weird scenario, edge scenario outside the CDI runtime:



                              • T2 calls destroy (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: destroy before init, at this point we are in the 4th dimension of CDI),

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).

                              Or



                              • T2 calls a method that access fooBean (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: T1 is initialized whereas fooBean has already been used by T2, at this point we are in the 4th dimension of CDI

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).





                              share|improve this answer


















                              • 1




                                thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                                – Nicolas Henneaux
                                Nov 12 at 13:57











                              • it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                                – Nicolas Labrot
                                Nov 12 at 14:19










                              • First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                                – Nicolas Henneaux
                                Nov 12 at 15:34







                              • 1




                                init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                                – Nicolas Labrot
                                Nov 12 at 16:07













                              up vote
                              1
                              down vote










                              up vote
                              1
                              down vote









                              According to the specification:




                              An event with qualifier @Initialized(ApplicationScoped.class) is synchronously fired when the application context is initialized.



                              An event with qualifier @BeforeDestroyed(ApplicationScoped.class) is synchronously fired when the application context is about to be destroyed, i.e. before the actual destruction.



                              An event with qualifier @Destroyed(ApplicationScoped.class) is synchronously fired when the application context is destroyed, i.e. after the actual destruction.




                              And according to this presentation Bean manager lifecycle: the lifecycle of the bean manager is synchronous between the different states of the process and the sequence is kept: "destroy not before init".



                              Jboss are the specification lead of CDI 2.0



                              I do not see any scenario that would require a volatile/protection. Even if T1 inits then T2 destroys, it will be T1 then T2, not T1 and T2 concurrently.



                              And even if it would be concurrently, to have an issue it would imply weird scenario, edge scenario outside the CDI runtime:



                              • T2 calls destroy (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: destroy before init, at this point we are in the 4th dimension of CDI),

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).

                              Or



                              • T2 calls a method that access fooBean (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: T1 is initialized whereas fooBean has already been used by T2, at this point we are in the 4th dimension of CDI

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).





                              share|improve this answer














                              According to the specification:




                              An event with qualifier @Initialized(ApplicationScoped.class) is synchronously fired when the application context is initialized.



                              An event with qualifier @BeforeDestroyed(ApplicationScoped.class) is synchronously fired when the application context is about to be destroyed, i.e. before the actual destruction.



                              An event with qualifier @Destroyed(ApplicationScoped.class) is synchronously fired when the application context is destroyed, i.e. after the actual destruction.




                              And according to this presentation Bean manager lifecycle: the lifecycle of the bean manager is synchronous between the different states of the process and the sequence is kept: "destroy not before init".



                              Jboss are the specification lead of CDI 2.0



                              I do not see any scenario that would require a volatile/protection. Even if T1 inits then T2 destroys, it will be T1 then T2, not T1 and T2 concurrently.



                              And even if it would be concurrently, to have an issue it would imply weird scenario, edge scenario outside the CDI runtime:



                              • T2 calls destroy (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: destroy before init, at this point we are in the 4th dimension of CDI),

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).

                              Or



                              • T2 calls a method that access fooBean (fooBean is null and now 'cached' in a register)

                              • Then T1 calls init: T1 is initialized whereas fooBean has already been used by T2, at this point we are in the 4th dimension of CDI

                              • Then T2 calls destroy (fooBean is already cached in a register so is value is null)).






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Nov 12 at 14:11

























                              answered Nov 12 at 13:00









                              Nicolas Labrot

                              2,8221728




                              2,8221728







                              • 1




                                thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                                – Nicolas Henneaux
                                Nov 12 at 13:57











                              • it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                                – Nicolas Labrot
                                Nov 12 at 14:19










                              • First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                                – Nicolas Henneaux
                                Nov 12 at 15:34







                              • 1




                                init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                                – Nicolas Labrot
                                Nov 12 at 16:07













                              • 1




                                thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                                – Nicolas Henneaux
                                Nov 12 at 13:57











                              • it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                                – Nicolas Labrot
                                Nov 12 at 14:19










                              • First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                                – Nicolas Henneaux
                                Nov 12 at 15:34







                              • 1




                                init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                                – Nicolas Labrot
                                Nov 12 at 16:07








                              1




                              1




                              thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                              – Nicolas Henneaux
                              Nov 12 at 13:57





                              thanks for the specification! However for cached value it doesn't need to be accessed to put in L* CPU cache. it doesn't even need to be concurrent calls. volatile provides the guarantees that the CPU caches does contain the latest value written by any thread. In case of concurrency between init and destroy it could happen that you get null value.
                              – Nicolas Henneaux
                              Nov 12 at 13:57













                              it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                              – Nicolas Labrot
                              Nov 12 at 14:19




                              it could happen that you get null value How and when? Cache is coherent and volatile on x86 is mostly about not caching into register not CPU cache
                              – Nicolas Labrot
                              Nov 12 at 14:19












                              First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                              – Nicolas Henneaux
                              Nov 12 at 15:34





                              First, imagine init and destroy execute at the same time and destroy reaches first the field fooBean, it would see null with or without volatile. Another situation when volatile could help, if one thread executes init while fooBean is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches. If destroy executes after without other operation on the cache it could see null without any violation in the Java specification.
                              – Nicolas Henneaux
                              Nov 12 at 15:34





                              1




                              1




                              init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                              – Nicolas Labrot
                              Nov 12 at 16:07





                              init and destroy execute at the same time: do we agree that this scenario is not possible? is cached on all L1 caches, it changes only value in the value in its core while the other cores still hold null in their L1 caches.: the cache coherence mechanism will ensure that in other L1 cache, the entries are invalidated. So if destroy executes after, it will not see null
                              – Nicolas Labrot
                              Nov 12 at 16:07


















                               

                              draft saved


                              draft discarded















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53227585%2fcdi-postconstruct-and-volatile-fields%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Use pre created SQLite database for Android project in kotlin

                              Darth Vader #20

                              Ondo