Singleton design pattern in java

Singleton pattern is a design solution where an application wants to have one and only one instance of any class, in all possible scenarios without any exceptional condition. It has been debated long enough in java community regarding possible approaches to make any class singleton. Still, you will find people not satisfied with any solution you give. They can not be overruled either. In this post, we will discuss some good approaches and will work towards our best possible effort.
Sections in this post:
  • Eager initialization
  • Lazy initialization
  • Static block initialization
  • Bill pugh solution
  • Using Enum
  • Adding readResolve()
  • Adding serial version id
  • Conclusion
Singleton term is derived from its mathematical counterpart. It wants us, as said above, to have only one instance. Lets see the possible solutions:

Eager initialization

This is a design pattern where an instance of a class is created much before it is actually required. Mostly it is done on system start up. In singleton pattern, it refers to create the singleton instance irrespective of whether any other class actually asked for its instance or not.
01.public class EagerSingleton {
02.private static volatile EagerSingleton instance = new EagerSingleton();
03. 
04.// private constructor
05.private EagerSingleton() {
06.}
07. 
08.public static EagerSingleton getInstance() {
09.return instance;
10.}
11.}
Above method works fine, but has one drawback. Instance is created irrespective of it is required in runtime or not. If this instance is not big object and you can live with it being unused, this is best approach.
Lets solve above problem in next method.

Lazy initialization

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. In singleton pattern, it restricts the creation of instance until requested first time. Lets see in code:
01.public final class LazySingleton {
02.private static volatile LazySingleton instance = null;
03. 
04.// private constructor
05.private LazySingleton() {
06.}
07. 
08.public static LazySingleton getInstance() {
09.if (instance == null) {
10.synchronized (LazySingleton.class) {
11.instance = new LazySingleton();
12.}
13.}
14.return instance;
15.}
16.}
On first invocation, above method will check if instance is already created using instance variable. If there is no instance i.e. instance is null, it will create an instance and will return its reference. If instance is already created, it will simply return the reference of instance.
But, this method also has its own drawbacks. Lets see how. Suppose there are two threads T1 and T2. Both comes to create instance and execute “instance==null”, now both threads have identified instance variable to null thus assume they must create an instance. They sequentially goes to synchronized block and create the instances. At the end, we have two instances in our application.
This error can be solved using double-checked locking. This principle tells us to recheck the instance variable again in synchronized block in given below way:
01.public class EagerSingleton {
02.private static volatile EagerSingleton instance = null;
03. 
04.// private constructor
05.private EagerSingleton() {
06.}
07. 
08.public static EagerSingleton getInstance() {
09.if (instance == null) {
10.synchronized (EagerSingleton.class) {
11.// Double check
12.if (instance == null) {
13.instance = new EagerSingleton();
14.}
15.}
16.}
17.return instance;
18.}
19.}
Above code is the correct implementation of singleton pattern.
Please ensure to use “volatile” keyword with instance variable otherwise you can run into out of order write error scenario, where reference of instance is returned before actually the object is constructed i.e. JVM has only allocated the memory and constructor code is still not executed. In this case, your other thread, which refer to uninitialized object may throw null pointer exception and can even crash the whole application.

Static block initialization

If you have little idea about class loading sequence, you can connect to the fact that static blocks are executed during the loading of class and even before the constructor is called. We can use this feature in our singleton pattern also like this:
01.public class StaticBlockSingleton {
02.private static final StaticBlockSingleton INSTANCE;
03. 
04.static {
05.try {
06.INSTANCE = new StaticBlockSingleton();
07.catch (Exception e) {
08.throw new RuntimeException("Uffff, i was not expecting this!", e);
09.}
10.}
11. 
12.public static StaticBlockSingleton getInstance() {
13.return INSTANCE;
14.}
15. 
16.private StaticBlockSingleton() {
17.// ...
18.}
19.}
Above code has one drawback. Suppose there are 5 static fields in class and application code needs to access only 2 or 3, for which instance creation is not required at all. So, if we use this static initialization. we will have one instance created though we require it or not.
Next section will overcome this problem.

Bill pugh solution

Bill pugh was main force behind java memory model changes. His principle “Initialization-on-demand holder idiom” also uses static block but in different way. It suggest to use static inner class.
01.public class BillPughSingleton {
02.private BillPughSingleton() {
03.}
04. 
05.private static class LazyHolder {
06.private static final BillPughSingleton INSTANCE = new BillPughSingleton();
07.}
08. 
09.public static BillPughSingleton getInstance() {
10.return LazyHolder.INSTANCE;
11.}
12.}
As you can see, until we need an instance, the LazyHolder class will not be initialized until required and you can still use other static members of BillPughSingleton class. This is the solution, i will recommend to use. I also use it in my all projects.

Using Enum

This type of implementation recommend the use of enum. Enum, as written in java docs, provide implicit support for thread safety and only one instance is guaranteed. This is also a good way to have singleton with minimum effort.
1.public enum EnumSingleton {
2.INSTANCE;
3.public void someMethod(String param) {
4.// some class member
5.}
6.}

Adding readResolve()

So, till now you must have taken your decision that how you would like to implement your singleton. Now lets see other problems that may arise even in interviews also.
Lets say your application is distributed and it frequently serialize the objects in file system, only to read them later when required. Please note that, de-serialization always creates a new instance. Lets understand using an example:
Our singleton class is:
01.public class DemoSingleton implements Serializable {
02.private volatile static DemoSingleton instance = null;
03. 
04.public static DemoSingleton getInstance() {
05.if (instance == null) {
06.instance = new DemoSingleton();
07.}
08.return instance;
09.}
10. 
11.private int i = 10;
12. 
13.public int getI() {
14.return i;
15.}
16. 
17.public void setI(int i) {
18.this.i = i;
19.}
20.}
Lets serialize this class and de-serialize it after making some changes:
01.public class SerializationTest {
02.static DemoSingleton instanceOne = DemoSingleton.getInstance();
03. 
04.public static void main(String[] args) {
05.try {
06.// Serialize to a file
07.ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
08."filename.ser"));
09.out.writeObject(instanceOne);
10.out.close();
11. 
12.instanceOne.setI(20);
13. 
14.// Serialize to a file
15.ObjectInput in = new ObjectInputStream(new FileInputStream(
16."filename.ser"));
17.DemoSingleton instanceTwo = (DemoSingleton) in.readObject();
18.in.close();
19. 
20.System.out.println(instanceOne.getI());
21.System.out.println(instanceTwo.getI());
22. 
23.catch (IOException e) {
24.e.printStackTrace();
25.catch (ClassNotFoundException e) {
26.e.printStackTrace();
27.}
28.}
29.}
30. 
31.Output:
32.20
33.10
Unfortunately, both variables have different value of variable “i”. Clearly, there are two instances of our class. So, again we are in same problem of multiple instances in application.
To solve this issue, we need to include readResolve() method in our DemoSingleton class. This method will be invoked when you will de-serialize the object. Inside this method, you must return the existing instance to ensure single instance application wide.
01.public class DemoSingleton implements Serializable {
02.private volatile static DemoSingleton instance = null;
03. 
04.public static DemoSingleton getInstance() {
05.if (instance == null) {
06.instance = new DemoSingleton();
07.}
08.return instance;
09.}
10. 
11.protected Object readResolve() {
12.return instance;
13.}
14. 
15.private int i = 10;
16. 
17.public int getI() {
18.return i;
19.}
20. 
21.public void setI(int i) {
22.this.i = i;
23.}
24.}
Now when you execute the class SerializationTest, it will give you correct output.
1.20
2.20

Adding serial version id

So far so good. Till now, we have solved the problem of synchronization and serialization both. Now, we are just one step behind our correct and complete implementation. And missing part is serial version id.
This is required in condition when you class structure can change in between you serialize the instance and go again to de-serialize it. Changed structure of class will cause JVM to give exception while de-serializing process.
1.java.io.InvalidClassException: singleton.DemoSingleton; local class incompatible: stream classdesc serialVersionUID = 5026910492258526905, local class serialVersionUID = 3597984220566440782
2.at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
3.at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
4.at java.io.ObjectInputStream.readClassDesc(Unknown Source)
5.at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
6.at java.io.ObjectInputStream.readObject0(Unknown Source)
7.at java.io.ObjectInputStream.readObject(Unknown Source)
8.at singleton.SerializationTest.main(SerializationTest.java:24)
This problem can be solved only by adding a unique serial version id to class. It will prevent the compiler to throw the exception by telling that both classes are same, and will load the available instance variables only.

Conclusion

After having discussed so many possible approaches and other possible error cases, i will recommend you below code template to design your singleton class which shall ensure only one instance of class in whole  application in all above discussed scenarios.
01.public class DemoSingleton implements Serializable {
02.private static final long serialVersionUID = 1L;
03. 
04.private DemoSingleton() {
05.// private constructor
06.}
07. 
08.private static class DemoSingletonHolder {
09.public static final DemoSingleton INSTANCE = new DemoSingleton();
10.}
11. 
12.public static DemoSingleton getInstance() {
13.return DemoSingletonHolder.INSTANCE;
14.}
15. 
16.protected Object readResolve() {
17.return getInstance();
18.}
19.}
I hope, this post has enough information to make you understand the most common approaches for singleton pattern. Let me know of you thoughts please.
Happy Learning !!

为什么GNU grep如此之快?

本文由 伯乐在线 - 敏敏 翻译自 FreeBSD Mailing Lists。欢迎加入技术翻译小组。转载请参见文章末尾处的要求。

编注:这是GNU grep的原作者Mike Haertel 在FreeBSD邮件列表中对 “GNU grep为什么比BSD grep要快” 所做的回答,下面是邮件正文内容:
Gabor 您好,
我是GNU grep的原作者,同时也是一名FreeBSD用户,不过我一直使用的是-stable版本(也就是更老的版本),而没怎么关注-current版本。
但是,当我无意间翻阅-current版的邮件列表时,偶然发现了一些关于BSD grep与GNU grep性能的讨论,你可能也注意到了那些讨论。
不管怎么说,仅供参考吧,下面是一些简单的总结,关于为什么GNU grep如此之快。或许你能借鉴其中的一些思想运用到BSD grep中去。
#技巧1:GNU grep之所以快是因为它并不会去检查输入中的每一个字节
#技巧2:GNU grep之所以快是因为它对那些的确需要检查的每个字节都执行非常少的指令(操作)
GNU grep使用了非常著名的Boyer-Moore算法(译者注:BM算法,是一种非常高效的字符串搜索算法,一般情况下,比KMP算法快3-5倍,具体可查看这篇讲解非常详细的文章:grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍),该算法首先从目标字符串的最后一个字符开始查找,并且使用一个查找表,它可以在发现一个不匹配字符之后,计算出可以跳过多少个输入字符并继续查找。
GNU grep还展开了Boyer-Moore算法的内部循环,并建立了一个Boyer-Moore的delta表,这样它就不需要在每一个展开的步骤进行循环退出判断了。这样的结果就是,在极限情况下(in the limit),GNU grep在需要检查的每一个输入字节上所执行的x86指令不会超过3条(并且还跳过了许多字节)。
你可以看看由Andrew Hume和Daniel Sunday 1991年11月在“Software Practice & Experience”上发表的论文“Fast String Searching”,该文很好的讨论了Boyer-Moore算法的实现技巧,该文有免费的PDF在线版(译者注:点这里查看或下载)。
一旦有了快速搜索,这时你会发现也需要同样快速的输入。
GNU grep使用了原生Unix输入系统调用并避免了在读取后对数据进行拷贝。
而且,GNU grep还避免了对输入进行分行,查找换行符会让grep减慢好几倍,因为要找换行符你就必须查看每个字节!
所以GNU grep没有使用基于行的输入,而是将原数据读入到一个大的缓冲区buffer,用Boyer-Moore算法对这个缓冲区进行搜索,只有在发现一个匹配之后才会去查找最近的换行符(某些命令参数,比如-n会禁止这种优化)。
最后,当我还在维护GNU grep的时候(15+年前……),GNU grep也尝试做一些非常困难的事情使内核也能避免处理输入的每个字节,比如使用mmap()而不是read()来进行文件输入。当时,用read()会使大部分Unix版本造成一些额外的拷贝。因为我已经不再GNU grep了,所以似乎mmap已经不再默认使用了,但是你仍然可以通过参数–mmap来启用它,至少在文件系统的buffer已经缓存了你的数据的情况下,mmap仍然要快一些:
1
2
3
4
5
6
7
8
$ time sh -c 'find . -type f -print | xargs grep -l 123456789abcdef'
  real  0m1.530s
  user  0m0.230s
  sys   0m1.357s
$ time sh -c 'find . -type f -print | xargs grep --mmap -l 123456789abcdef'
  real  0m1.201s
  user  0m0.330s
  sys   0m0.929s
[这里使用的输入是一个648M的MH邮件文件夹,包含大约41000条信息]
所以即使在今天,使用–mmap仍然可以提速20%以上。
总结:
- 使用Boyer-Moore算法(并且展开它的内层循环)。
- 使用原生系统调用来建立你的缓冲输入,避免在搜索之前拷贝输入字节。(无论如何,最好使用缓冲输出,因为在grep的常用场景中,输出的要比输入的少,所以输出缓冲拷贝的开销要小,并且可以节省许多这样小的无缓冲写操作。)
- 在找到一个匹配之前,不要查找换行符。
- 尝试做一些设置(比如页面对齐缓冲区,按页大小来读取块,选择性的使用mmap),这样可以使内核避免拷贝字节。
让程序变得更快的关键就是让它们做更少的事情。;-)
致礼
Mike