Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Singleton Implementation: Java

DZone's Guide to

Singleton Implementation: Java

Part of a collection of posts implementing the classic design pattern, this time in Java.

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

A Singleton implementation, in Java.

Implementation: Java

Like most object-oriented typed languages, Java makes it pretty straightforward to code up a classic Singleton:

public class Product
{
  private Product() { }

  public static Product Instance() {
    return instance;
  }
  private static Product instance = new Product();

  public void DoSomething() {
    state++;
    System.out.println("I'm doing something for the " + state + " time");
  }
  private int state = 0;
}

public class Main
{
  public static void main(String... args) {
    Product.Instance().DoSomething();
    Product.Instance().DoSomething();
    Product.Instance().DoSomething();
  }
}

Like most of its kin, Java Singletons are eagerly initialized, in that the Singleton is initialized and ready as soon as the class is loaded, but like most dynamically-loaded runtimes (the JVM and the CLR are both such creatures), the class won’t be loaded until it is explicitly referenced somehow.(Accessing the static method is one such way to force the class-load.)

Java will usually use a static method, since it lacks any sort of property syntax.

Concurrent access

The JVM being a multi-threaded platform, it should usually be assumed that the Singleton can and will be accessed from multiple threads (whether that was originally intended or not!). As a result, some level of concurrency-safety needs to be implemented on the instance; one such (potentially naive) way of doing so is to mark the relevant methods as “synchronized,” though the preferable approach is to hide the concurrency-safety details a little bit more deeply:

import java.util.concurrent.locks.*;

public class ThreadsafeProduct
{
  private ThreadsafeProduct() { }

  public static ThreadsafeProduct Instance() {
    return instance;
  }
  private static ThreadsafeProduct instance = new ThreadsafeProduct();

  public void DoSomething() {
    lock.lock();
    try {
      state++;
      System.out.println("I'm doing something for the " + state + " time");
    }
    finally {
      lock.unlock();
    }
  }
  private int state = 0;
  private Lock lock = new ReentrantLock();
}

public class Main
{
  public static void main(String... args) {
    ThreadsafeProduct.Instance().DoSomething();
    ThreadsafeProduct.Instance().DoSomething();
    ThreadsafeProduct.Instance().DoSomething();
  }
}

NOTE: This is not to imply that the above is a particularly good concurrent implementation; such a subject is well beyond the intent of this example, and interested parties are referred to JCiP for (much) more detail.

Thread-scoped Singleton

As it turns out, a related concurrency example of Singletons is also an example of “scoping” Singletons differently than traditionally assumed. Java makes available a ThreadLocal class that will implicitly store the value, but store separate values per Thread. The Javadocs for it show some basic usage:

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {
  // Atomic integer containing the next thread ID to be assigned
  private static final AtomicInteger nextId = new AtomicInteger(0);

  // Thread local variable containing each thread's ID
  private static final ThreadLocal<Integer> threadId =
    new ThreadLocal<Integer>() {
      @Override protected Integer initialValue() {
        return nextId.getAndIncrement();
    }
  };

  // Returns the current thread's unique ID, assigning it if necessary
  public static int get() {
    return threadId.get();
  }
}

Each time ThreadId.get() is called, the “thread-specific Singleton” thread ID will be returned.

 

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:
java ,design patterns ,singleton pattern ,implementation

Published at DZone with permission of Ted Neward, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}