5 Replies Latest reply on Jun 30, 2011 6:52 AM by 802316

    Thread Safety for Object References within Methods

    808688
      Hi,

      If for example I have a class like this
      public class MyClass {
          private final ServiceFactory serviceFactory = new ServiceFactory();
      
          public MyClass() {
              super();
          }
      
          public void doSomething() {
              final Service service = serviceFactory.getService();
              String name = service.getName();
              System.out.println(name);
          }
      }
      and ServiceFactory is not specified as being thread safe and is third-party (we can't change it). Is the method doSomething() thread-safe? If (as I suspect) not, is there anyway to provided multithreaded access safely to this class without resulting in ThreadLocal for the ServiceFactory?

      Thanks,
      Simon
        • 1. Re: Thread Safety for Object References within Methods
          jtahlborn
          no, it's not thread-safe. you could probably make it thread-safe by synchronizing on the serviceFactory instance (note, i say probably because it's always possible that the implementation could do something to make this code unsafe):
              public void doSomething() {
                  synchronized(serviceFactory) {
                    final Service service = serviceFactory.getService();
                    String name = service.getName();
                    System.out.println(name);
                  }
              }
          Edited by: jtahlborn on Jun 29, 2011 1:00 PM
          • 2. Re: Thread Safety for Object References within Methods
            796440
            SimonKent wrote:
            Hi,

            If for example I have a class like this
            public class MyClass {
            private final ServiceFactory serviceFactory = new ServiceFactory();
            
            public MyClass() {
            super();
            }
            
            public void doSomething() {
            final Service service = serviceFactory.getService();
            String name = service.getName();
            System.out.println(name);
            }
            }
            and ServiceFactory is not specified as being thread safe and is third-party (we can't change it). Is the method doSomething() thread-safe?
            That depends. If getService() is guaranteed to get you a new Service, or at least one that's currently not in use, and if Service's thread-unsafety is entirely confined to the state of that Service object itself (as opposed to Services sharing some other resource without syncing), then, yes, it's threadsafe.

            If any of those conditions cannot be guaranteed to be true, however, then, no, it is not.
            If (as I suspect) not, is there anyway to provided multithreaded access safely to this class without resulting in ThreadLocal for the ServiceFactory?
            Not sure why you're trying to avoid ThreadLocal. There are times when it's appropriate and quite handy. Assuming you have a legitimate reason not to use it, the only approach I can suggest without knowing the entire context is that every use of a given Service object has to be synchronized on the same lock, and the most obvious choice for that is the Service itself.
            • 3. Re: Thread Safety for Object References within Methods
              jtahlborn
              jverd wrote:
              SimonKent wrote:
              and ServiceFactory is not specified as being thread safe and is third-party (we can't change it). Is the method doSomething() thread-safe?
              That depends. If getService() is guaranteed to get you a new Service, or at least one that's currently not in use, and if Service's thread-unsafety is entirely confined to the state of that Service object itself (as opposed to Services sharing some other resource without syncing), then, yes, it's threadsafe.
              note, he said ServiceFactory is not guaranteed to be thread-safe. even if getService() returns you a distinct Service, it could involve manipulating the internals of ServiceFactory in a way which is not thread-safe.
              1 person found this helpful
              • 4. Re: Thread Safety for Object References within Methods
                796440
                jtahlborn wrote:
                jverd wrote:
                SimonKent wrote:
                and ServiceFactory is not specified as being thread safe and is third-party (we can't change it). Is the method doSomething() thread-safe?
                That depends. If getService() is guaranteed to get you a new Service, or at least one that's currently not in use, and if Service's thread-unsafety is entirely confined to the state of that Service object itself (as opposed to Services sharing some other resource without syncing), then, yes, it's threadsafe.
                note, he said ServiceFactory is not guaranteed to be thread-safe.
                Oops. Mis-read.
                even if getService() returns you a distinct Service, it could involve manipulating the internals of ServiceFactory in a way which is not thread-safe.
                Yup. Absolutely.
                • 5. Re: Thread Safety for Object References within Methods
                  802316
                  When locking an object it is worth limiting the scope of the lock especially any blocking or long running operations.
                  public void doSomething() {
                        final String name;
                        synchronized(serviceFactory) {
                            final Service service = serviceFactory.getService();
                            name = service.getName();
                        }
                        System.out.println(name);
                  }
                  It is possible you need the output to be in a particular order, however unlessthis is needed, you may find this improves performance significantly.