设计模式——享元模式(Flyweight Pattern)

定义:享元模式又称轻量级模式,是对象池的一种实现,类似于线程池,可以避免频繁的创建销毁对象,消耗性能。目的是共享对象资源,将多个对同一对象的访问集中起来。属于结构型模式。

应用场景:经常应用与系统底层开发,当有大量相似对象,或者相同对象需要频繁创建、销毁,需要用到缓冲池的场景。

享元模式一般和单例模式配合使用,将享元工厂声明为一个单例类来池化享元对象。

// 享元工厂:类似于线程池统一管理对象
public class FlyweightFactory {
    private static Map pool = new HashMap();
    public static IFlyweight getFlyweight(String key) {
        if (!pool.containsKey(key)) {
            IFlyweight flyweight = new ConcreteFlyweight(key);
            pool.put(key, flyweight);
        }
        return pool.get(key);
    }
}

源码中享元模式的应用

String常量池

jdk对String类型常量做了优化处理,相同内容的常量会指向同一块内存空间

public class FlyweightTest {
    public static void main(String[] args) {
        String s1 = "hello"; //常量
        String s2 = "hello"; //常量
        String s3 = "he" + "llo"; //编译阶段已经做了处理,等同于上面的常量
        String s4 = new String("hello"); //创建了新的内存空间
        String s5 = "he" + new String("llo"); //创建了新的内存空间
        String s6 = s4.intern(); //取出内存中的常量值
        String s7 = "he";
        String s8 = "llo";
        String s9 = s7 + s8; //编译阶段不会变量做优化处理

        System.out.println(s1 == s2); // true
        System.out.println(s1 == s3); // true
        System.out.println(s1 == s4); // false
        System.out.println(s1 == s5); // false
        System.out.println(s1 == s6); // true
        System.out.println(s1 == s9); // false
        System.out.println(s4 == s5); // false
        System.out.println(s4 == s9); // false
        System.out.println(s5 == s9); // false
    }
}

Integer缓存池

jdk对Integer做了优化处理,经常使用的数字(-128 ~ 127之间)会缓存起来,直接从缓存池获取,不会重新创建

public class FlyweightTest {
    public static void main(String[] args) {
        Integer a = Integer.valueOf(100);
        Integer b = Integer.valueOf(100);
        Integer c = 100;
        Integer d = Integer.valueOf(128);
        Integer e = Integer.valueOf(128);
        Integer f = 128;
        System.out.println(a == b); //true
        System.out.println(a == c); //true
        System.out.println(d == e); //false
        System.out.println(d == f); //false
    }
}

介于-128到127之间的数字,会从缓存池中获取,否则会创建

public final class Integer extends Number implements Comparable {

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
        }
        //....
    }

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
}

你可能感兴趣的:(设计模式,设计模式,享元模式)