前言
單例模式是寫代碼過程中不可避免用到的哀澈,下面我總結(jié)一下單例常用的五中寫法
加載類時創(chuàng)建單例
- Java實現(xiàn)
public class Config{
private static Config INSTANCE=new Config();
private Config(){
//構(gòu)造函數(shù)
}
public static Config getInstance(){
return INSTANCE;
}
}
- Kotlin實現(xiàn)
object Config{}
上面這種寫法簡單粗暴曙求,直接在加載類的時候創(chuàng)建碍庵,但這樣會拖慢啟動進程,因此悟狱,可以在用到的時候再加載静浴,比如下面這種寫法
懶加載寫法
- Java實現(xiàn)
public class Config{
private static Config INSTANCE;
private Config(){
//構(gòu)造函數(shù)
}
public static Config getInstance(){
if(null==INSTANCE){
INSTSANCE=new Config();
}
return INSTANCE;
}
}
- Kotlin實現(xiàn)
public class Config{
companion object{
val instance by lazy(LazyThreadSafetyMode.NONE){
Config()
}
}
}
懶加載雖然避免在加載類的時候創(chuàng)建,但是線程不安全挤渐,如果同時多個類獲取單例苹享,有可能會創(chuàng)建多個單例,因此可以在創(chuàng)建單例的時候加線程鎖浴麻,比如下面這種寫法:
同步鎖寫法
- Java實現(xiàn)
public class Config{
private static Config INSTANCE;
private Config(){
//構(gòu)造函數(shù)
}
public static synchronized Config getInstance(){
if(null==INSTANCE){
INSTANCE=new Config();
}
return INSTANCE;
}
}
- Kotlin實現(xiàn)
class Config{
companion object{
private var instance:Config?=null
@Synchronized
fun get():Config{
if(nnull==instance) instance=Config()
return instance
}
}
}
同步鎖避免單例不會被重復(fù)創(chuàng)建得问,但是同步鎖
雙重校驗寫法
- Java實現(xiàn)
public class Config{
private static volatile Config INSTANCE;
private Config(){
//構(gòu)造函數(shù)
}
public static Config getInstance(){
if(null==INSTANCE){
synchronized(Config.class){
if(null==INSTANCE){
INSTSANCE=new Config();
}
}
}
return INSTANCE;
}
}
- Kotlin實現(xiàn)
class Config{
companion object{
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
Config()
}
}
}
靜態(tài)內(nèi)部類寫法
這種寫法避免了類加載的時候初始化單例,同時將同步鎖問題交給虛擬機處理软免,算得上是最優(yōu)雅的寫法宫纬,Java和Kotlin寫法幾乎是一模一樣
- Java實現(xiàn)
public class Config{
private static class Helper{
private static Config INSTANCE=new Config();
}
private Config(){
//構(gòu)造函數(shù)
}
public static Config getInstance(){
return Helper.INSTANCE;
}
}
- Kotlin實現(xiàn)
class Config private constructor(){
companion object{
fun getInstance = Helper.instance
}
private object Helper{
val instance = Config()
}
}