Header javaperspective.com
JavaPerspective.com  >   Advanced Tutorials  >   4. Miscellaneous Java features  >   4.3. Singletons

4.3. Singletons
Last updated: 25 January 2013.

A singleton is a class that can be instantiated only once. In a multithreaded application, you may need to ensure that only a sole instance of a certain class can be created. Typically, a singleton has a private constructor which prevents other classes from instantiating it with the keyword new. Moreover, a singleton provides a getInstance method which returns a single instance of itself. Here is an example:

public final class Singleton {

   
// Declare a static Singleton object
   
private static Singleton instance;


   
/* Declare a private constructor to prevent other classes from
     * creating instances of Singleton with the keyword "new"
     */
   
private Singleton(){

    }


   
/* Implement a static synchronized "getInstance" method that returns
     * a unique instance of Singleton
     */
   
public static synchronized Singleton getInstance(){
         
if(instance == null)
               
instance = new Singleton();

         
return instance;
   
}


   
// Other non-static methods
   
public void doSomething(){
         
// ...
          // ...
   
}

}

As you can see, the code is quite simple. The class Singleton cannot be instantiated with the keyword new from another class since its constructor is not visible. The only way to get an instance of Singleton is by calling the static method getInstance. For example, here is a call to the method doSomething:

Singleton.getInstance().doSomething();

The method getInstance is declared as a synchronized method so that two threads cannot execute it simultaneously. Without the synchronized keyword, before any instance of Singleton is created, two threads might enter the method getInstance concurrently and create two instances of Singleton.

Singletons are often used to get a single instance of a class but also when you need to execute only once initialization code in the constructor. As an example, the class ConnectionPool shown below is a modified version of the class with the same name that you might have already seen in the tutorial Connection pooling. In the new version, ConnectionPool is a singleton. As its name implies, it initializes a JDBC connection pool in its constructor (with the Proxool library) and provides a getConnection method which returns a connection borrowed from the pool.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public final class ConnectionPool {

   
private static ConnectionPool instance;

   
private ConnectionPool() throws Exception {
         
// Set up the URL
         
String alias = "demo"; // The alias uniquely identifies the pool
         
String driverClass = "oracle.jdbc.driver.OracleDriver";
          String driverUrl =
"jdbc:oracle:thin:@localhost:1521:orcl";
          String url =
"proxool." + alias + ":" + driverClass + ":" + driverUrl;

         
// Set up the Properties object
         
Properties info = new Properties();
          info.setProperty
("proxool.maximum-connection-count", "30");
          info.setProperty
("user", "yourName");
          info.setProperty
("password", "yourPassword");

         
// Initialize the pool, borrow a connection and return it to the pool by calling "close"
          // If something goes wrong, an exception is thrown
         
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
          Connection connection = DriverManager.getConnection
(url, info);
          connection.close
();
   
}

   
public static synchronized ConnectionPool getInstance() throws Exception{
         
if(instance == null)
               
instance = new ConnectionPool();

         
return instance;
   
}


   
public Connection getConnection() throws SQLException {
         
// Use the alias "demo" defined in the constructor to borrow a connection
         
return DriverManager.getConnection("proxool.demo");
   
}

}

To get a connection from the pool, the code would be the following:

try {
   
Connection connection = ConnectionPool.getInstance().getConnection();
   
// Do something with the connection
    // ...
}
catch (Exception e) {
   
e.printStackTrace();
}

Singletons come in handy when you want to have a single instance of a class in your application. However, in a multithreaded application, performance is degraded because the method getInstance is synchronized. For this reason, developers should not overuse singletons, as they can significantly degrade the overall performance of an application.

In fact, there are relatively similar situations where performance can be preserved because, instead of having a single instance of a class for the whole application, you need a single instance per thread. In that case, you should use a ThreadLocal as explained in the next tutorial.


You are here :  JavaPerspective.com  >   Advanced Tutorials  >   4. Miscellaneous Java features  >   4.3. Singletons
Next tutorial :  JavaPerspective.com  >   Advanced Tutorials  >   4. Miscellaneous Java features  >   4.4. The class ThreadLocal

Copyright © 2013. JavaPerspective.com. All rights reserved.  ( Terms | Contact | About ) 
Java is a trademark of Oracle Corporation
Image 1 Image 2 Image 3 Image 4 Image 5 Image 6 Image 7