单线程
// Singleton.java
public class Singleton {
private static Singleton instance;
private Singleton() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// Demo.java
public class Demo {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
Singleton singleton1 = Singleton.getInstance();
System.out.println(singleton == singleton1);
}
}
多线程问题(返回结构不一致)
// Singleton.java
public class Singleton {
private static Singleton instance;
public String value;
private Singleton(String value) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.value = value;
}
public static Singleton getInstance(String value) {
if (instance == null) {
instance = new Singleton(value);
}
return instance;
}
}
// Demo.java
public class Demo {
public static void main(String[] args) {
Thread threadFoo = new Thread(new ThreadFoo());
Thread threadBar = new Thread(new ThreadBar());
threadFoo.start();
threadBar.start();
}
static class ThreadFoo implements Runnable {
@Override
public void run() {
Singleton singleton = Singleton.getInstance("Foo");
System.out.println(singleton.value);
}
}
static class ThreadBar implements Runnable {
@Override
public void run() {
Singleton singleton = Singleton.getInstance("Bar");
System.out.println(singleton.value);
}
}
}
多线程解决方法(采用延迟加载的线程安全单例)
// Singleton.java
public class Singleton {
// volatile保证双端检锁正确工作
private static volatile Singleton instance;
public String value;
private Singleton(String value) {
this.value = value;
}
public static Singleton getInstance(String value) {
Singleton result = null;
if (result != null) {
return result;
}
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(value);
}
return instance;
}
}
}
// Demo.java
public class Demo {
public static void main(String[] args) {
Thread threadFoo = new Thread(new ThreadFoo());
Thread threadBar = new Thread(new ThreadBar());
threadFoo.start();
threadBar.start();
}
static class ThreadFoo implements Runnable {
@Override
public void run() {
Singleton singleton = Singleton.getInstance("Foo");
System.out.println(singleton.value);
}
}
static class ThreadBar implements Runnable {
@Override
public void run() {
Singleton singleton = Singleton.getInstance("Bar");
System.out.println(singleton.value);
}
}
}