怎樣用c語言做網(wǎng)站北京seo推廣系統(tǒng)
目錄
一、定義?
二、應(yīng)用場景?
三、具體實現(xiàn)
示例一
示例二
四、懶漢與餓漢
餓漢模式
懶漢模式
五、總結(jié)
六、說明
一、定義?
二、應(yīng)用場景?
?單例模式的應(yīng)用場景主要包括以下幾個方面:
-
?日志系統(tǒng):在應(yīng)用程序中,通常只需要一個日志系統(tǒng),通過單例模式可以避免在多個地方創(chuàng)建多個日志對象,降低資源消耗。?
-
?數(shù)據(jù)庫連接池:數(shù)據(jù)庫連接池是一個重要的資源,使用單例模式可以確保應(yīng)用程序中只有一個數(shù)據(jù)庫連接池實例,從而避免資源浪費(fèi)。
-
?配置文件管理器:為了管理應(yīng)用程序的配置文件,通常只需要一個配置文件管理器實例。單例模式可以確保整個應(yīng)用程序中只有一個配置文件管理器實例。
-
?緩存系統(tǒng):緩存系統(tǒng)是提高應(yīng)用程序性能的關(guān)鍵組件,使用單例模式可以確保整個應(yīng)用程序中只有一個緩存實例。
-
?GUI組件:在圖形用戶界面(GUI)開發(fā)中,單例模式可以確保整個應(yīng)用程序中只有一個GUI組件實例,以保持用戶界面的一致性和穩(wěn)定性。
-
?讀取配置信息:如果配置信息需要在程序啟動時加載,并且只需讀取一次,那么可以使用單例模式來讀取配置文件。?
此外,單例模式還適用于那些創(chuàng)建對象時資源消耗大,但又需要頻繁訪問該對象的場景,或者需要對系統(tǒng)內(nèi)的資源進(jìn)行統(tǒng)一的讀寫操作的場景,比如進(jìn)行配置文件的讀寫操作。?
總的來說,單例模式通常適用于在整個應(yīng)用程序中只需要一個實例化對象的場景,以確保資源的高效利用和應(yīng)用程序的穩(wěn)定性。
三、具體實現(xiàn)
示例一
“ 需求:對于項目中的 JSON 要格式化處理對象,采用 雙檢鎖單例模式 進(jìn)行管理,從而復(fù)用對象,避免重復(fù)創(chuàng)建對象的開銷 ”
實現(xiàn):
創(chuàng)建單例:
import com.fasterxml.jackson.databind.ObjectMapper;// JsonFormatter 類負(fù)責(zé)管理 ObjectMapper 對象,它是 Jackson 庫中用于處理 JSON 的核心類。public class JsonFormatter {private static volatile JsonFormatter instance;private ObjectMapper objectMapper;// 私有構(gòu)造方法,防止外部實例化private JsonFormatter() {// 初始化 ObjectMapperobjectMapper = new ObjectMapper();// 可以在這里配置 ObjectMapper 的特性,例如日期格式化、空字段處理等}// 獲取單例實例的靜態(tài)方法
// 使用雙檢鎖(double-checked locking)來確保在多線程環(huán)境下只創(chuàng)建一個 JsonFormatter 實例。public static JsonFormatter getInstance() {if (instance == null) {
//volatile 關(guān)鍵字確保在多線程環(huán)境中正確地處理 instance 變量,防止指令重排序帶來的問題。synchronized (JsonFormatter.class) {if (instance == null) {instance = new JsonFormatter();}}}return instance;}// 提供了一個公共方法來格式化 JSON 字符串,可以將對象轉(zhuǎn)換為 JSON 格式的字符串。public String formatJson(Object obj) {try {return objectMapper.writeValueAsString(obj);} catch (Exception e) {e.printStackTrace();return null;}}
}
?使用單例:
public class MyApp {public static void main(String[] args) {JsonFormatter jsonFormatter = JsonFormatter.getInstance();// 示例對象MyObject obj = new MyObject("John Doe", 30);// 格式化為 JSON 字符串String jsonString = jsonFormatter.formatJson(obj);System.out.println("Formatted JSON: " + jsonString);}
}
?
?????????使用雙檢鎖單例模式來管理 JSON 格式化處理對象,確保在整個項目中只有一個 JsonFormatter
實例存在,避免了重復(fù)創(chuàng)建對象的開銷,同時提供了一個便捷的方式來操作 JSON 數(shù)據(jù)的格式化。這種方式非常適合在需要頻繁處理 JSON 數(shù)據(jù)的項目中,可以顯著提升性能和資源利用率。
示例二
“需求:通過單例模式可以確保配置信息在整個系統(tǒng)中只有一個實例,避免多次加載配置文件或多次訪問數(shù)據(jù)庫”
實現(xiàn):
創(chuàng)建配置信息類:這個類負(fù)責(zé)加載和存儲配置信息
// ConfigManager.java - 單例模式的配置管理器
// ConfigManager 類可以進(jìn)一步擴(kuò)展,例如支持從文件中加載配置、支持動態(tài)更新配置、支持不同環(huán)境的配置切換等。這樣,通過單例模式管理配置信息,能夠有效地避免多次加載配置文件或訪問數(shù)據(jù)庫,提高系統(tǒng)性能和管理便捷性。public class ConfigManager {private static ConfigManager instance;
//靜態(tài)單例實例變量,使用 private static 關(guān)鍵字聲明了一個靜態(tài)的 instance 變量,用于保存 ConfigManager 類的唯一實例。private String configFile; // 用于存儲配置文件名或配置內(nèi)容// 私有構(gòu)造方法,防止外部實例化private ConfigManager() {// 加載配置文件或初始化配置內(nèi)容this.configFile = "config.properties"; // 示例配置文件名// 實際應(yīng)用中可以在構(gòu)造方法中進(jìn)行配置文件的加載// 例如:this.loadConfig();}// 公有靜態(tài)方法,獲取唯一實例,getInstance() 方法是獲取 ConfigManager 類的實例的唯一入口。這個方法使用了雙重檢查鎖定(double-checked locking)來確保在多線程環(huán)境下也能保持單例的唯一性和線程安全性。public static ConfigManager getInstance() {if (instance == null) {synchronized (ConfigManager.class) {if (instance == null) {instance = new ConfigManager();}}}return instance;}// 示例方法:獲取配置信息public String getConfig() {return this.configFile;}// 示例方法:設(shè)置配置信息public void setConfig(String configFile) {this.configFile = configFile;}
}
?實現(xiàn)單例模式:確保在整個應(yīng)用中只有一個配置信息實例。
public class MyApp {public static void main(String[] args) {ConfigManager configManager = ConfigManager.getInstance();// 獲取配置信息示例String configFile = configManager.getConfig();System.out.println("Current config file: " + configFile);// 修改配置信息示例configManager.setConfig("new_config.properties");System.out.println("Updated config file: " + configManager.getConfig());}
}
????????整個 ConfigManager
類符合單例模式的要求:它保證了在整個應(yīng)用程序中只有一個實例存在,并提供了全局訪問點來獲取這個唯一的實例。這樣做可以確保配置信息在整個系統(tǒng)中只有一個實例,避免了多次加載配置文件或多次訪問數(shù)據(jù)庫的問題。?
四、懶漢與餓漢
一文搞懂設(shè)計模式—單例模式
在選擇單例模式的創(chuàng)建方式時,通??梢赃x擇懶漢模式或餓漢模式,具體取決于項目的需求和使用場景。讓我們來比較一下懶漢模式和餓漢模式的特點和適用場景:
餓漢模式
在餓漢模式下,實例在類加載時就被創(chuàng)建,因此稱為“餓漢”——因為它一開始就“吃飽了”。
特點:
- 線程安全:由于實例在類加載時就創(chuàng)建并初始化,所以不存在多線程環(huán)境下的線程安全問題。
- 簡單:實現(xiàn)起來比較簡單,沒有復(fù)雜的同步控制。
- 性能較好:在訪問量較大或者對性能有一定要求的場景下,由于不需要在獲取實例時進(jìn)行同步操作,性能較好。
適用場景:
- 當(dāng)單例對象的創(chuàng)建和初始化操作比較簡單,且在程序運(yùn)行時就需要頻繁使用時,可以考慮使用餓漢模式。
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {// 私有構(gòu)造方法}public static Singleton getInstance() {return instance;}
}
懶漢模式
在懶漢模式下,實例在第一次使用時才進(jìn)行創(chuàng)建,因此稱為“懶漢”——直到需要才“吃”。
特點:
- 延遲加載:只有在首次調(diào)用?
getInstance()
?方法時才會創(chuàng)建實例。 - 線程安全性需要考慮:如果不加同步控制,在多線程環(huán)境下可能會創(chuàng)建多個實例。
- 資源利用率高:只有在需要時才會創(chuàng)建對象,節(jié)省了資源。
適用場景:
- 當(dāng)單例對象的創(chuàng)建和初始化操作較為復(fù)雜或者需要延遲加載時,可以考慮使用懶漢模式。
- 如果應(yīng)用中頻繁使用單例對象的情況不多,懶漢模式可以節(jié)省資源。
示例(帶雙重檢查鎖定的懶漢模式):
public class Singleton {private static volatile Singleton instance;private Singleton() {// 私有構(gòu)造方法}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
五、總結(jié)
- 餓漢模式適合在單例對象比較簡單,且在程序整個生命周期內(nèi)需要頻繁使用的情況下,可以提升性能。
- 懶漢模式適合在單例對象創(chuàng)建和初始化較為復(fù)雜,或者需要延遲加載的情況下,以節(jié)省資源并避免不必要的初始化。
????????具體如何選擇呢,像示例一中的代碼,使用懶漢模式(帶雙重檢查鎖定)是比較合適的選擇。因為:
-
延遲加載:你的
JsonFormatter
類中的ObjectMapper
實例需要在第一次調(diào)用getInstance()
方法時才被初始化。這種延遲加載的方式可以節(jié)省資源,特別是在應(yīng)用程序啟動時,可能不立即需要操作 JSON 的情況下。 -
線程安全性:通過雙重檢查鎖定,確保了在多線程環(huán)境下只會創(chuàng)建一個
JsonFormatter
實例。這種方式在保證線程安全的同時,又能避免每次調(diào)用getInstance()
都進(jìn)行同步,提高了性能。 -
資源利用:由于
ObjectMapper
可能比較重量級(尤其是在配置了特定的序列化/反序列化規(guī)則時),懶漢模式可以避免不必要的對象創(chuàng)建和初始化,從而提高了資源的利用率。
六、說明
日志管理上使用@Slf4j 中的log 這個注解里面沒有用到單例模式