前言
單例模式是寫代碼過程中不可避免用到的,下面我總結一下單例常用的五中寫法
加載類時創(chuàng)建單例
- Java實現(xiàn)
public class Config{
private static Config INSTANCE=new Config();
private Config(){
//構造函數(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(){
//構造函數(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(){
//構造函數(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
}
}
}
同步鎖避免單例不會被重復創(chuàng)建,但是同步鎖
雙重校驗寫法
- Java實現(xiàn)
public class Config{
private static volatile Config INSTANCE;
private Config(){
//構造函數(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)內部類寫法
這種寫法避免了類加載的時候初始化單例,同時將同步鎖問題交給虛擬機處理,算得上是最優(yōu)雅的寫法,Java和Kotlin寫法幾乎是一模一樣
- Java實現(xiàn)
public class Config{
private static class Helper{
private static Config INSTANCE=new Config();
}
private Config(){
//構造函數(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()
}
}