享元模式:解决对象的复用问题,提供第三方的管理,不破坏类的封装
      自行实例化对象,不像单例时强制保证
池化资源管理:
  享元工厂也可以初始化多个对象---其他地方需要使用对象可以找工厂拿(修改个状态)--用完之后在放回来(状态修改回来)
  避免重复的创建和销毁资源(特别是对于非托管资源,像:数据库连接,线程)
享元模式:
1.实现一:
 public class FlyweightFactory
    {
        private static Dictionary<WordType, BaseWorld> FlyweightFactoryDictionary = new Dictionary<WordType, BaseWorld>();
        /// <summary>
        /// 1.如果是5个线程同时调用,字典为空,所以会同时构造5次E
        /// 2.最后只只打印一个ELEVEN,因为其他线程都挂掉了,因为在字典中添加相同的值的时候,挂掉了
        /// 3. 2个L是小概率事件,前两个线程是同时添加E,所以没有失败,所以L有两个,但是到L的时候又冲突了
        /// 4.子线程的异常时看不到的,除非waitall
        /// </summary>
        /// <param name="wordType"></param>
        /// <returns></returns>
        public static BaseWorld CreateWord(WordType wordType)
        {
            if (!FlyweightFactoryDictionary.ContainsKey(wordType))
            {
                BaseWorld word = null;
                switch (wordType)
                {
                    case WordType.E:
                        word = new E();
                        break;
                    case WordType.L:
                        word = new L();
                        break;
                    case WordType.V:
                        word = new V();
                        break;
                    case WordType.N:
                        word = new N();
                        break;
                    default:
                        throw new Exception();
                }
                FlyweightFactoryDictionary.Add(wordType, word);
            }
            return FlyweightFactoryDictionary[wordType];
        }
    }
    public enum WordType
    {
        E,
        L,
        V,
        N
    }
测试代码:
 for (int i = 0; i < 5; i++)
                {
                    Task.Run(() => 
                    {
                        BaseWorld e = FlyweightFactory.CreateWord(WordType.E);
                        BaseWorld l = FlyweightFactory.CreateWord(WordType.L);
                        BaseWorld V = FlyweightFactory.CreateWord(WordType.V);
                        BaseWorld n = FlyweightFactory.CreateWord(WordType.N);
                        Console.WriteLine("{0}{1}{2}{3}{4}{5}", e.Get(), l.Get(), e.Get(), V.Get(), e.Get(), n.Get());
                    });
                }
测试结果:

2.实现方式二:
public class FlyweightFactory
    {
        private static Dictionary<WordType, BaseWorld> FlyweightFactoryDictionary = new Dictionary<WordType, BaseWorld>();
        /// <summary>
        /// 不想看到多线程的时候生成多个E,加锁
        /// </summary>
        private readonly static object FlyweightFactoryLock = new object();
        /// <summary>
        /// 1.如果是5个线程同时调用,字典为空,所以会同时构造5次E
        /// 2.最后只只打印一个ELEVEN,因为其他线程都挂掉了,因为在字典中添加相同的值的时候,挂掉了
        /// 3. 2个L是小概率事件,前两个线程是同时添加E,所以没有失败,所以L有两个,但是到L的时候又冲突了
        /// 4.子线程的异常时看不到的,除非waitall
        /// </summary>
        /// <param name="wordType"></param>
        /// <returns></returns>
        public static BaseWorld CreateWord(WordType wordType)
        {
            if (!FlyweightFactoryDictionary.ContainsKey(wordType))
                //是为了性能优化,避免对象已经被初始化后,再次请求还需要等待锁
            {
                lock (FlyweightFactoryLock)//相当于Monitor.Enter, 保证方法体只有一个线程可以进入
                {
                    if (!FlyweightFactoryDictionary.ContainsKey(wordType))
                    {
                        BaseWorld word = null;
                        switch (wordType)
                        {
                            case WordType.E:
                                word = new E();
                                break;
                            case WordType.L:
                                word = new L();
                                break;
                            case WordType.V:
                                word = new V();
                                break;
                            case WordType.N:
                                word = new N();
                                break;
                            default:
                                throw new Exception();
                        }
                        FlyweightFactoryDictionary.Add(wordType, word);
                    }
                }
            }
                
            return FlyweightFactoryDictionary[wordType];
        }
    }
    public enum WordType
    { 
        E,
        L,
        V,
        N
    }
测试结果:

原文:https://www.cnblogs.com/fblogs/p/12313751.html