1 / 8

Steven Seida

Singleton Fun. Steven Seida. Multi-Threading Problem. public class Foo { private Foo myInstance; private Foo() {} … public static Foo getInstance() { if (myInstance==null) { myInstance = new Foo(); } } } //class foo. Result is Multiple Instances. Time Step --1-- --2--

Download Presentation

Steven Seida

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Singleton Fun Steven Seida

  2. Multi-Threading Problem • public class Foo { • private Foo myInstance; • private Foo() {} • … • public static Foo getInstance() { • if (myInstance==null) { • myInstance = new Foo(); • } • } • } //class foo Result is Multiple Instances Time Step --1-- --2-- --3-- --4-- --5-- Process #2 public static Foo getInstance() { if (myInstance==null) { myInstance = new Foo(); } Process #1 public static Foo getInstance() { if (myInstance==null) { myInstance = new Foo(); }

  3. Simple Fix – Synchronized Method No two threads may enter the method at the same time. • public class Foo { • private Foo myInstance; • private Foo() {} • … • public static synchronized Foo getInstance() { • if (myInstance==null) { • myInstance = new Foo(); • } • } • … • } //class foo • Causes blocking around any calls to getInstance() • Works but may be more costly than we can afford.

  4. Improve Multi-Threading Option 1 • Need to lock on creation of the variable, rather than an entire method. • public class Foo { • private static Foo myInstance = new Foo(); • private Foo() {} • … • public static Foo getInstance() { • myInstance = new Foo(); • } • … • } //class foo Greedy initialization is guaranteed to be thread safe.

  5. Improve Multi-Threading Option 2 • Need to lock on creation of the variable, rather than an entire method. • public class Foo { • private volatile static Foo myInstance; • private Foo() {} • … • public static Foo getInstance() { • if (myInstance == null) { • synchronized (Foo.class) { • if (myInstance == null) { • myInstance = new Foo(); • } • } • } • return myInstance; • } • … • } //class foo Never cached thread-locally – always writes/read with ‘main memory’. Only synchronize the first time through. Confirm someone else didn’t beat you here.

  6. Volatile and Synchronized* • Declaring a volatile Java variable means: • The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"; • Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself. • We say "acts as though" in the second point, because to the programmer at least (and probably in most JVM implementations) there is no actual lock object involved. *http://www.javamex.com/tutorials/synchronization_volatile.shtml# Applicable to Java 5 and later

  7. Comparison of Synchronized and Volatile

  8. Synchronized vs Volatile • In other words, the main differences between synchronized and volatile are: • a primitive variable may be declared volatile (whereas you can't synchronize on a primitive with synchronized); • an access to a volatile variable never has the potential to block: we're only ever doing a simple read or write, so unlike a synchronized block we will never hold on to any lock; • because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation (unless we're prepared to "miss an update"); • a volatile variable that is an object reference may be null (because you're effectively synchronizing on the reference, not the actual object). • Note: Attempting to synchronize on a null object will throw a NullPointerException.

More Related