JAVA設(shè)計(jì)模式---單例模式你知道嗎
單例模式的介紹

單例模式實(shí)現(xiàn)的八種方式

餓漢式
靜態(tài)常量
步驟:
1.構(gòu)造器私有化(防止new)
2.類的內(nèi)部創(chuàng)建對(duì)象
3.向外暴露一個(gè)靜態(tài)的公共方法—getInstance
//餓漢式靜態(tài)常量
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)常量
private final static Singleton instance=new Singleton();
//提供一個(gè)公有的靜態(tài)方法,返回一個(gè)實(shí)例對(duì)象
public static Singleton getInstance()
{
return instance;
}
}
public class Main
{
public static void main(String[] args)
{
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}

靜態(tài)代碼塊
//餓漢式靜態(tài)常量
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)常量
private static Singleton instance;
//在靜態(tài)代碼塊中,創(chuàng)建單例對(duì)象
static
{
instance=new Singleton();
}
//提供一個(gè)公有的靜態(tài)方法,返回一個(gè)實(shí)例對(duì)象
public static Singleton getInstance()
{
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
靜態(tài)代碼塊的優(yōu)缺點(diǎn)

懶漢式
線程不安全的寫法
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)常量
private static Singleton instance;
//提供一個(gè)公有的靜態(tài)方法
//當(dāng)使用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象
//即懶漢式
public static Singleton getInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
優(yōu)缺點(diǎn)

線程安全,同步鎖—效率低,不推薦
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)常量
private static Singleton instance;
//提供一個(gè)公有的靜態(tài)方法
//當(dāng)使用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象
//即懶漢式
//給當(dāng)前靜態(tài)方法加上一個(gè)同步鎖,這樣所有的對(duì)象就是一把鎖
//多個(gè)對(duì)象同時(shí)調(diào)用此方法,會(huì)按順序依次調(diào)用
public static synchronized Singleton getInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
優(yōu)缺點(diǎn)

線程安全,同步代碼塊—無(wú)法解決線程安全問(wèn)題,不推薦
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)常量
private static Singleton instance;
//提供一個(gè)公有的靜態(tài)方法
//當(dāng)使用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象
//即懶漢式
public static Singleton getInstance()
{
if(instance==null)
{
//鎖的是代碼塊
//鎖的對(duì)象是當(dāng)前類的字節(jié)碼文件對(duì)象,即當(dāng)前類的所有勢(shì)力對(duì)象擁有一把鎖
synchronized(Singleton.class)
{
instance=new Singleton();
}
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
優(yōu)缺點(diǎn)

雙重檢查—解決線程安全和懶加載問(wèn)題–推薦使用
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)常量
//volatile 保證變量在多線程下的可見性,即每個(gè)線程獲取到當(dāng)前變量的值是最新的值
private static volatile Singleton instance;
//提供一個(gè)公有的靜態(tài)方法
//當(dāng)使用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象
public static Singleton getInstance()
{
//加入雙重檢查問(wèn)題,解決線程安全,同時(shí)解決懶加載問(wèn)題
if(instance==null)
{
//鎖的是代碼塊
//鎖的對(duì)象是當(dāng)前類的字節(jié)碼文件對(duì)象,即當(dāng)前類的所有勢(shì)力對(duì)象擁有一把鎖
synchronized(Singleton.class)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
優(yōu)缺點(diǎn)

靜態(tài)內(nèi)部類—可以實(shí)現(xiàn)懶加載,線程安全,推薦使用
靜態(tài)內(nèi)部類在調(diào)用時(shí),才會(huì)加載
當(dāng)一個(gè)Java類第一次被真正使用到的時(shí)候靜態(tài)資源被初始化、Java類的加載和初始化過(guò)程都是線程安全的
class Singleton
{
//構(gòu)造器私有化,外部不能new
private Singleton(){}
//靜態(tài)內(nèi)部類
private static class SingletonInstance{
//靜態(tài)屬性
private static final Singleton INSTANCE=new Singleton();
}
public static Singleton getInstance()
{
//該方法調(diào)用時(shí),靜態(tài)內(nèi)部類加載,里面的靜態(tài)屬性才會(huì)賦值
return SingletonInstance.INSTANCE;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
優(yōu)缺點(diǎn)

枚舉
enum Singleton
{
//枚舉常量
INSTANCE;
//底層: public static final Singleton INSTANCE= new Singleton ();
//方法
public void getInstance()
{
System.out.println("得到實(shí)例");
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.INSTANCE;
Singleton s2=Singleton.INSTANCE;
s1.getInstance();
s2.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
優(yōu)缺點(diǎn)

單例模式注意事項(xiàng)

總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java實(shí)現(xiàn)直接插入排序和折半插入排序算法示例
這篇文章主要介紹了Java實(shí)現(xiàn)直接插入排序和折半插入排序算法示例,文中對(duì)算法的思想和時(shí)間復(fù)雜度都有簡(jiǎn)單的講解,需要的朋友可以參考下2016-04-04
解決SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find
這篇文章主要介紹了SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find a @SpringBootConfiguration,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
使用 Java8 實(shí)現(xiàn)觀察者模式的方法(下)
這篇文章主要介紹了使用 Java8 實(shí)現(xiàn)觀察者模式的方法(下)的相關(guān)資料,需要的朋友可以參考下2016-02-02
Spring?Security中自定義cors配置及原理解析
在Spring框架中,通過(guò)自定義CORS配置可根據(jù)實(shí)際情況調(diào)整URL的協(xié)議、主機(jī)、端口等,以適應(yīng)"同源安全策略",配置原理涉及CorsConfigurer和CorsFilter,自定義配置需要注意@Configuration注解、方法名以及可能的@Autowired注解2024-10-10
LeetCode?動(dòng)態(tài)規(guī)劃之矩陣區(qū)域和詳情
這篇文章主要介紹了LeetCode?動(dòng)態(tài)規(guī)劃之矩陣區(qū)域和詳情,文章基于Java的相關(guān)資料展開對(duì)LeetCode?動(dòng)態(tài)規(guī)劃的詳細(xì)介紹,需要的小伙伴可以參考一下2022-04-04
java實(shí)現(xiàn)簡(jiǎn)單的學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02

