字符串驻留池的另类用法

起因

事情的起因是这样的

基于某些无法避免的因素

我有2个dll 暂且叫 a.dll 和 b.dll

这2个类库中有一部分完全相同的代码(下文中称为代码C)——遍历当前应用程序下的所有类库文件,并注入插件(没错,就是IOC了)

当开发人员仅引用a.dll或仅b.dll的时候,并没有任何问题

但是如果一个项目需要同时引用 a.dll 和 b.dll 那么麻烦就来了

那部分完全相同的代码会被执行2次, 所有插件都会被加载2次

经过

最简单的方案当然是把a.dll和b.dll中相同的代码 抽出成c.dll

然后之前引用a.dll的 需要同时引用a.dll和c.dll

虽然可以很简单的解决问题,但是同样他的修改成本和用户体验是最差的(软件设计也要用户体验),

这个方案被保留为无论如何都无法解决问题才会使用的方案

由于a.dll和b.dll互相不知道对方的存在,所以无法直接通知对方我已经执行过代码C了

想过中Mutex,也想过用反射,都因为有各种副作用而放弃了

其他更多中间尝试各种方案的过程就不说了...

结果

最后灵光一闪,猛然想到了字符串驻留池(不了解的自己百度,或者搜博客园相关文章)

string.Intern 将字符串放入驻留池

string.IsInterned 返回字符串在驻留池中的引用,如果返回null则说明该字符串没有在驻留池中

突然就有了主意了:约定一个字符串,当任何一个代码C被执行的时候,先判断这个字符串是否在驻留池中,如果不在则执行代码,执行完成后将这个字符串放入驻留池

当然这里有一个需要注意的地方,字符串如果直接固定写带代码中,在编译期间就会被放入驻留池

栗子中,xxx是硬编码在代码中的  可以看出xxx在驻留池中,而NewGuid的字符串 没有在驻留池中

所有硬编码的string都会被编译成常量,常量字符串也是在驻留池中的

加上字符串是引用类型,但是有常量的概念这个特性,所以全局锁也搞定了,直接锁定一个常量字符串就行了

所以 实际项目中的代码如下:

时间: 2024-11-10 07:15:51

字符串驻留池的另类用法的相关文章

JAVA 字符串驻留池

一切从String str = new String("abc")说起...    这行代码形式上很简单,其实很复杂.有一个常见的Java笔试题就是问上面这行代码创建了几个String对象.    我刚开始很自然的觉得应该是创建了一个String对象,后来查阅资料,才发现,实际上创建了两个String对象.下面说明为什么创建了两个String对象.    首先,来了解一下Java中的字符串驻留池的概念.JVM为了提高性能,将一下两种形式的字符串放在一个称之为字符串驻留池的内存块中:  

.Net字符串驻留池

在.Net中,对于相同的字符串,.Net会将它们指向同一个地址,它们是相同的实例..Net中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.Net实际上是新创建一个字符串,而将变量地址指向新创建的字符串地址. string s1 = "Hello"; string s2 = "Hello"; bool b = Object.ReferenceEquals(s1, s2); Console.WriteLine(b); //输入 True 它们是同一

(一)Python入门-2编程基本概念:18字符串-驻留机制-内存分析-字符串同一判断-值相等判断

一:字符串驻留 仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串驻留池中. Python 支持字符串驻留机制,对于符合标识符规则的字符串(仅包含下划线(_).字母 和数字)会启用字符串驻留机制驻留机制. 二:字符串比较和同一性 我们可以直接使用==,!=对字符串进行比较,是否含有相同的字符. 我们使用is / not is,判断两个对象是否为同一个对象.比较的是对象的地址,即 id(obj1)是 否和 id(obj2)相等. 三:成员操作符 in /not in 关键字,判断某个字符(

C#中字符串的内存分配与驻留池

刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例.如下: String s1 = "Hello";String s2 = "Hello"; //s2和s1的实际值都是"Hello"bool same = (object) s1 == (object) s2; //这里比较s1.s2是否引用了同一个对象实例 //所以不能写作bool same =

C#中的string驻留池

刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例.如下: String s1 = "Hello";String s2 = "Hello"; //s2和s1的实际值都是"Hello"bool same = (object) s1 == (object) s2; //这里比较s1.s2是否引用了同一个对象实例 //所以不能写作bool same =

Java中String类型的不可变性和驻留池

一 基本概念 可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当获得这个类的一个实例引用时,可以改变这个实例的内容. 不可变类:不可变类的实例一但创建,其内在成员变量的值就不能被修改.其中String类就是不可变类的经典应用. 二 例子 package cn.xy.test; public class StringTest{ /**  * a的值在编译时就被确定下来,故其值"xy"被放入String的驻留池(驻留池在堆中)并被a指向.

Python中的字符串驻留

C#中的字符串驻留 熟悉.NET的人都应该知道C#中的字符串驻留机制,.NET维护了一个驻留池,它会把在编译期间就相同的字符串只保留一份拷贝.如果仅在运行期间值才相同的字符串变量,.NET不会为这个2个相同的字符串变量指向同一份引用的.不过.NET提供了一个方法,让开发人员可以强制将两个相同的字符串指向同一个引用,使用String类中的Intern方法. string s1 = "!QAZ2wsx3$%5$$%fe _ ###[email protected]"; string s2 

写在Github被微软收购之际 - Github的那些另类用法

这几天朋友圈被微软75亿美元收购Github的新闻刷屏了.Jerry也来贡献一篇和Github相关的文章. 这篇文章包含了Jerry平时对于Github的一些另类用法.目录如下: 1. 部署HTML应用到Github并运行 2. Github和云平台的集成 3. ABAP Git客户端 4. 用Github搭建个人博客 5. 一些提高工作效率的小窍门 6. Github周边 如果您也有使用Github的小技巧,欢迎留言. 1. 部署HTML应用到Github并运行 这个技巧其实是把Github作

Java中的字符串常量池

最近做到一个题目: 问题:String str = new String("abc"),"abc"在内存中是怎么分配的?    答案是:堆,字符串常量区. 题目考查的为Java中的字符串常量池和JVM运行时数据区的相关概念."abc"为字面量对象,其存储在堆内存中.而字符串常量池则存储的是字符串对象的一个引用. Java中的字符串常量池 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid&qu