Join Elisabeth Robson for an in-depth discussion in this video Dealing with multithreading, part of Foundations of Programming: Design Patterns.
Now that you've seen how to implement Singleton, we should cover some issues that can crop up when using it, as well as how we deal with those issues. To understand these issues, let's return to the Singleton code where, in the getInstance method, we've checked to see if there's already a unique instance. And if so, we return it. If there's not, we then create a new instance and return it. Now, we've been to this code a bit, and it may seem fairly bulletproof, like it always does the right thing, but, there's a case where it might not, and that case is where we're using multiple threads. Let's step through the execution of two threads, Thread one and Thread two.
Here's the hypothetical, but also very possible, path of execution through this code by these two threads. First, thread one checks if unique is null. And if it is, it enters the block to create the new Singleton object. About this time, thread two get's it's turn. And it also checks unique for null. Which it is. And so it enters the block to create a new instance of Singleton. Thread one gets to run again, and it creates a new Singleton, assigns it to unique, and returns it. Thread two then runs, creates another Singleton object, assigns it to unique, overwriting the original reference to the Singleton and returns that.
So, we have two callers that now have references to two different Singletons. That's a problem. So what do we do? Well, here is some ideas. We can make sure that getInstance method is synchronized in some way, so the two threads can't get near the state of execution. Or, perhaps we could create a Singleton and not do it the way we are here with lazy instantiation. Let's step through some code to see how we might fix this.
- What are design patterns?
- Encapsulating code that varies with the strategy pattern
- Setting behavior dynamically
- Implementing the observer pattern
- Creating chaos with inheritance
- Extending behavior with composition
- Dealing with multithreading and the singleton pattern
- Revising the design for a state machine
- Encapsulating iteration with the collection pattern
- Encapsulating object creation with the factory method pattern
Skill Level Intermediate
Q: How do I import the exercise files in Eclipse?
<div>A: Here are instructions for importing the files: </div> <div> </div> <div>1) Save the download folder as any name you choose, such as DesignPatternsLynda. Place this folder in the default Eclipse project folder (the folder you choose when you start Eclipse). </div> <div>2) Start Eclipse. </div> <div>3) In Eclipse, choose File > New > New Java Project. </div> <div>4) In the first New Project dialog box, use the folder name from step 1 as the project name. Check that the location path matches the default Eclipse project path and the name of the folder. (See NewProject.jpg.)</div> <div><img src="http://files.lynda.com/files/prodfaqs/NewProject.jpg" border="0" alt="" /><br /> </div> <div>5) Click Next. </div> <div>6) In this dialog box, leave all settings as is (see Step2.jpg):</div> <div><img src="http://files.lynda.com/files/prodfaqs/Step2.jpg" border="0" alt="" /><br /> </div> <div>7) Click Finish. </div> <div>8) You should now have a project in Eclipse with the following structure (see EclipseProjectStructure.jpg):</div> <div><img src="http://files.lynda.com/files/prodfaqs/EclipseProjectStructure.jpg" border="0" alt="" /><br /> </div> <div>9) To compile the code, open the folder you want to work with and choose the main class. </div> <div>10) Choose Run > Run As > Java Application.</div>