Singleton Implementation: Java
Singleton Implementation: Java
Part of a collection of posts implementing the classic design pattern, this time in Java.
Join the DZone community and get the full member experience.
Join For FreeA 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.
Published at DZone with permission of Ted Neward , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}