單例模式結(jié)構(gòu)
單線(xiàn)程
// 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);
}
}
多線(xiàn)程問(wèn)題(返回結(jié)構(gòu)不一致)
// 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);
}
}
}
多線(xiàn)程解決方法(采用延遲加載的線(xiàn)程安全單例)
// 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);
}
}
}