單例實現方式一,鎖機制
public class Singleton {
private static Singleton singleton=null;
public Singleton() {
}
public static Singleton getIntance(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
單例實現方式二,靜態內部類
public class Singleton {
private static class SingletonHolder {
private static final Singleton singleton = new Singleton();
}
public Singleton() {
}
public static Singleton getIntance() {
return SingletonHolder.singleton;
}
}
靜態內部類雖然沒有顯示調用synchronized,但是借助ClassLoad的線程安全機制,隱式調用了synchronized
單例實現方式三,CAS操作
public class Singleton {
private static final AtomicReference<Singleton> instance = new AtomicReference<>();
public Singleton() {
}
public static Singleton getIntance() {
for (; ; ) {
Singleton singleton = instance.get();
if (singleton == null) {
singleton = new Singleton();
instance.compareAndSet(null, singleton);
}
return singleton;
}
}
public static class SingletonHold implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + Singleton.getIntance());
}
}
public static void main(String[] args) {
SingletonHold singletonHold = new SingletonHold();
Thread thread1 = new Thread(singletonHold);
Thread thread2 = new Thread(singletonHold);
Thread thread3 = new Thread(singletonHold);
thread1.start();
thread2.start();
thread3.start();
}
}
運行結果:
Thread-0:com.rongke.web.Singleton@7249381e
Thread-1:com.rongke.web.Singleton@7249381e
Thread-2:com.rongke.web.Singleton@7249381e
使用cas好處:不需要使用鎖來實現線程安全,而是依賴底層硬件實現,減少了因為鎖導致線程切換和阻塞的性能開銷,可以支持較大的並行度
使用cas缺點:如果線程一直處於for無限循環中,對cpu性能影響很大,如果多個線程執行singleton=new Singleton(),會產出堆內存浪費。