真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何實(shí)現(xiàn)Singleton模式

如何實(shí)現(xiàn)Singleton模式,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)制作、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、博樂(lè)ssl等。為成百上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的博樂(lè)網(wǎng)站制作公司

題目

設(shè)計(jì)一個(gè)類,我們只能生成該類的一個(gè)實(shí)例

分析

最簡(jiǎn)單實(shí)現(xiàn)

  • 私有構(gòu)造方法

  • 靜態(tài)方法獲取實(shí)例

是否需要考慮內(nèi)存或并發(fā)環(huán)境

如果需要考慮內(nèi)存,使用到時(shí)才創(chuàng)建實(shí)例對(duì)象(餓漢),不使用時(shí)就不創(chuàng)建實(shí)例(懶漢,懶加載)。

如果需要考慮線程安全,就要確保獲取實(shí)例是同步的,避免創(chuàng)建多個(gè)實(shí)例。

實(shí)現(xiàn)方式

  • [x] 1. 單線程(懶漢式、餓漢式)

  • [x] 2. 多線程工作效率不高(加鎖獲取實(shí)例的方法)

  • [x] 3. 加同步鎖前后兩次判斷實(shí)例是否已存在

  • [x] 4. 利用靜態(tài)初始化創(chuàng)建實(shí)例(推薦,線程安全,會(huì)占用一部分內(nèi)存)

  • [x] 5. 利用靜態(tài)內(nèi)部類實(shí)現(xiàn)按需創(chuàng)建實(shí)例(最推薦,線程安全,效率高,聰明的你應(yīng)該可以明白的)

編碼實(shí)現(xiàn)

1. 單線程(懶漢式、餓漢式)

餓漢單例
package cn.jast.java.offer.singleton;

/**
 * 簡(jiǎn)單餓漢單例
 *
 */
public class SimpleHungerSingleton {

    private static SimpleHungerSingleton simpleSingleton;

    private SimpleHungerSingleton(){
        simpleSingleton = new SimpleHungerSingleton();
    }

    public static SimpleHungerSingleton getInstance(){
        return simpleSingleton;
    }

}
簡(jiǎn)單懶漢單例
package cn.jast.java.offer.singleton;

/**
 * 簡(jiǎn)單懶漢單例
 * 
 */
public class SimpleLazySingleton {

    private static SimpleLazySingleton simpleSingleton;

    private SimpleLazySingleton(){

    }

    public static SimpleLazySingleton getInstance(){
        if(simpleSingleton == null){
            simpleSingleton = new SimpleLazySingleton();
        }
        return simpleSingleton;
    }

}
線程安全測(cè)試
/**
     * 測(cè)試簡(jiǎn)單單例的線程安全
     */
    public static void testSimpleLazySingleton(){
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                SimpleLazySingleton simpleLazySingleton = SimpleLazySingleton.getInstance();
                singletonSet.add(simpleLazySingleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }

輸出:

簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:
[cn.jast.java.offer.singleton.SimpleLazySingleton@2b9283d, cn.jast.java.offer.singleton.SimpleLazySingleton@72fba635]

2. 多線程工作效率不高(加鎖獲取實(shí)例的方法)

package cn.jast.java.offer.singleton;

public class Synchronized1Singleton {

    private static Synchronized1Singleton instance;

    private Synchronized1Singleton(){

    }

    /**
     * 每次獲取對(duì)象時(shí)都加鎖來(lái)確保創(chuàng)建對(duì)象
     * @return
     */
    public static synchronized Synchronized1Singleton getInstance(){
        if(instance == null){
            instance = new Synchronized1Singleton();
        }
        return instance;
    }
}

測(cè)試:

public static void testSynchronized1Singleton(){
        long startTime = System.currentTimeMillis();
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                Synchronized1Singleton singleton = Synchronized1Singleton.getInstance();
                singletonSet.add(singleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                System.out.println(String.format("執(zhí)行時(shí)間:%s ms",System.currentTimeMillis()-startTime));
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }

輸出:

執(zhí)行時(shí)間:72 ms(注:一個(gè)樣例)

3. 加同步鎖前后兩次判斷實(shí)例是否已存在

package cn.jast.java.offer.singleton;

public class Synchronized2Singleton {

    private static Synchronized2Singleton instance;

    private Synchronized2Singleton(){

    }

    public static Synchronized2Singleton getInstance(){
        if(instance == null){
            synchronized (Synchronized2Singleton.class){
                if(instance==null){
                    instance = new Synchronized2Singleton();
                }
            }
        }
        return instance;
    }

}

4. 利用靜態(tài)初始化創(chuàng)建實(shí)例(推薦,線程安全

package cn.jast.java.offer.singleton;

/**
 * 推薦
 */
public class StaticInitializeSingleton {

    private static StaticInitializeSingleton instance ;

    static{
        instance = new StaticInitializeSingleton();
    }

    private StaticInitializeSingleton(){

    }

    public static StaticInitializeSingleton getInstance(){
        return instance;
    }
}

5. 利用靜態(tài)內(nèi)部類實(shí)現(xiàn)按需創(chuàng)建實(shí)例(最推薦,線程安全,效率高

package cn.jast.java.offer.singleton;

/**
 * 推薦
 */
public class StaticInnerClassSingleton {

    private StaticInnerClassSingleton(){

    }

    public static StaticInnerClassSingleton getInstance(){
        return Inner.instance;
    }


    private static class Inner{
        private static final StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
    }
}

完整的測(cè)試

package cn.jast.java.offer.singleton;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

    public static void main(String[] args) {
//        testSimpleLazySingleton();
        testSynchronized1Singleton();
//        testSynchronized2Singleton();
//        testStaticInitializeSingleton();
//        testNestedClassSingleton();
    }


    /**
     * 測(cè)試簡(jiǎn)單單例的線程安全
     */
    public static void testSimpleLazySingleton(){
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                SimpleLazySingleton simpleLazySingleton = SimpleLazySingleton.getInstance();
                singletonSet.add(simpleLazySingleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }

    /**
     * 測(cè)試線程安全的單例模式實(shí)現(xiàn)
     */
    public static void testSynchronized1Singleton(){
        long startTime = System.currentTimeMillis();
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                Synchronized1Singleton singleton = Synchronized1Singleton.getInstance();
                singletonSet.add(singleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                System.out.println(String.format("執(zhí)行時(shí)間:%s ms",System.currentTimeMillis()-startTime));
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }

    /**
     * Synchronized2Singleton 的效率比 Synchronized1Singleton高幾倍甚至幾十倍以上
     */
    public static void testSynchronized2Singleton(){
        long startTime = System.currentTimeMillis();
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                Synchronized2Singleton singleton = Synchronized2Singleton.getInstance();
                singletonSet.add(singleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                System.out.println(String.format("執(zhí)行時(shí)間:%s ms",System.currentTimeMillis()-startTime));
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }

    /**
     *
     */
    public static void testStaticInitializeSingleton(){
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                Synchronized2Singleton singleton = Synchronized2Singleton.getInstance();
                singletonSet.add(singleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }

    public static void testNestedClassSingleton(){
        Set singletonSet = Collections.synchronizedSet(new HashSet<>());
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            executorService.submit(()->{
                StaticInnerClassSingleton singleton = StaticInnerClassSingleton.getInstance();
                singletonSet.add(singleton);
            });
        }
        executorService.shutdown();
        while(true){
            if(executorService.isShutdown()){
                if(singletonSet.size()>1){
                    System.out.println("簡(jiǎn)單單例存在創(chuàng)建多個(gè)實(shí)例對(duì)象,實(shí)例如下:");
                    System.out.println(singletonSet);
                }
                break;
            }

        }
    }
}

自問(wèn)自答

問(wèn):?jiǎn)卫J将@取實(shí)例的方法為什么是靜態(tài)方法? 答:因?yàn)闃?gòu)造方法是私有的,無(wú)法通過(guò)new創(chuàng)建實(shí)例,那只能通過(guò)類方法獲取實(shí)例。那通過(guò)反射是否可以創(chuàng)建實(shí)例呢?

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。


當(dāng)前名稱:如何實(shí)現(xiàn)Singleton模式
URL標(biāo)題:http://weahome.cn/article/jdegps.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部