单线程下安全使用的Singleton示例
public class Singleton {
private static Singleton instance = null;
private Singleton() {
System.out.println("create instance.");
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public static void main(String[] agrs) {
new Singleton();
}
}
单线程代码放到多线程下,将会出现线程不安全情况
class SingletonTestRunnable implements Runnable {
public void run() {
Singleton.getInstance();
}
}
public class Singleton {
private static Singleton instance = null;
private Singleton() {
System.out.println("create instance.");
}
public static Singleton getInstance() {
if (instance == null) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton();
}
System.out.println("instance hashCode : " + instance.hashCode());
return instance;
}
public static void main(String[] agrs) {
new Thread(new SingletonTestRunnable()).start();
new Thread(new SingletonTestRunnable()).start();
}
}
多线程Singleton反模式——使用synchronized修饰方法
public static synchronized Singleton getInstance() {
....
}
添加synchronized关键字确实可以解决多线程安全问题,但是仍然认为是反模式。原因是执行效率低,getInstance()方法只允许一个线程进入,阻塞会增加程序运行时间。
★多线程Singleton最佳实践——eager模式
class SingletonTestRunnable implements Runnable {
public void run() {
Singleton.getInstance();
}
}
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
System.out.println("create instance.");
}
public static Singleton getInstance() {
return instance;
}
public static void main(String[] agrs) {
new Thread(new SingletonTestRunnable()).start();
new Thread(new SingletonTestRunnable()).start();
}
}
★多线程Singleton最佳实践——lazy模式
class SingletonTestRunnable implements Runnable {
public void run() {
Singleton.getInstance();
}
}
public class Singleton {
private Singleton() {
System.out.println("create instance.");
}
public static Singleton getInstance() {
return Container.instance;
}
private static class Container {
private static Singleton instance = new Singleton();
}
public static void main(String[] agrs) {
new Thread(new SingletonTestRunnable()).start();
new Thread(new SingletonTestRunnable()).start();
}
}
--heipark