![丨immutability模式如何利用不变性解决并发问题_第1页](http://file4.renrendoc.com/view/2acfeab86154604da38b3b108680ecf1/2acfeab86154604da38b3b108680ecf11.gif)
![丨immutability模式如何利用不变性解决并发问题_第2页](http://file4.renrendoc.com/view/2acfeab86154604da38b3b108680ecf1/2acfeab86154604da38b3b108680ecf12.gif)
![丨immutability模式如何利用不变性解决并发问题_第3页](http://file4.renrendoc.com/view/2acfeab86154604da38b3b108680ecf1/2acfeab86154604da38b3b108680ecf13.gif)
![丨immutability模式如何利用不变性解决并发问题_第4页](http://file4.renrendoc.com/view/2acfeab86154604da38b3b108680ecf1/2acfeab86154604da38b3b108680ecf14.gif)
![丨immutability模式如何利用不变性解决并发问题_第5页](http://file4.renrendoc.com/view/2acfeab86154604da38b3b108680ecf1/2acfeab86154604da38b3b108680ecf15.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实现一个具备不可变性的类,还是挺简单的。将一个类所有的属性都设置成nal的,并且只允许存在只读方法,那么这个类基本上就具备不可变性了。更严格的做法是nal,也就是不允许继承。因为子类可以覆盖父类的方法,有可能改变不可变性,所以推荐你在实际工作中,使用这种更严格的做法。JaaK里很多类都具备不可变性,只是由于它们的使用太简单,最后反而被忽略了。例如经常用到的g和Intoube的、属性和方法,你会发现它们都严格遵守不可变类的三点要求:类和属性都是nal的,所有方法均是只读的。看到这里你可能会疑惑,JavaString法也有类似字符替换操作,怎么能说所有方法都是只读的呢?我们结合String的源代码来解释一下这个问题,下面的示例代码源自Java1.8SDK,我略做了修改,仅保留了关键属性value[]和rece()方法,你会发现:String这个类以及它的属性value[]都是final的;而rece()方法的实现,就的确没有修改value[],而是将替换后的字符串作为返回值返回了。代码publicfinalclassStringprivatefinalchar//字符替Stringrece(charcharnewChar)//无需替换,直接返回if(oldChar==return intlen=inti=-/*avoidgetfieldopcodechar[]val=//定位到需要替换的字符位while(++i<len)if(val[i]==oldChar) //未找到oldChar,无需替if(i>=len)return //创建一个buf[],这是关//用来保存替换后的字charbuf[]=newfor(intj=0;j<i;j++)buf[j]= while(i<len)charc=buf[i]=(c==oldChar)newChar: //创建一个新的字符串//原字符串不会发生任何变returnnewString(buf, 41g创建一个新的不可变对象象的一个重要区别,可变对象往往是修改自己的属性。Pattern)。利用享元模式可以减少创建对象的数量,从而减少内存占用。Java里面Long、Integer、Short、Byte等这些基本数据类型的包装类都用到了享元模式。下面我们就以Long这个类作为例子,看看它是如何利用享元模式来优化对象的享元模式本质上其实就是一个对象池,利用享元模式创建对象的逻辑也很简单:创建之前,首先去对象池里看看是不是存在;如果已经存在,就利用对象池里的对象;如果不存在,就会新创建一个对象,并且把这个新创建出来的对象放进对象池里。Long这个类并没有照搬享元模式,Long内部了一个静态的对象池,仅缓存[-128,127]之间的数字,这个对象池在JVM启动的时候就创建好了,而且这个对象池一都不会变化,也就是说它是静态的。之所以采用这样的设计,是因为Long这个对象的状共有264种,实在太多,不宜全部缓存,而[-128,127]之间的数字利用率最高。下面的示例代码出自Java1.8,valueOf()方法就用到了LongCache这个缓存,你可以结合着来加代码LongvalueOf(longl)finalintoffset=//[-128,127]直接的数字做了缓if(l>=-128&&l<=127)return.cache[(int)l+ returnnew9//缓存,等价于对象//仅缓存[-128,127]直接的数staticclassLongCachestaticfinalLong=newLong[-(-128)+127+staticfor(inti=0;i<cache.length;cache[i]=newLong(i-}}前面我们在《13|理论基础模块热点问题答疑》中提到“Integer和String类型的对象不模式,这会导致看上去私有的锁,其实是共有的。例如在下面代码中,本意是A用锁al,B用锁bl,各自管理各自的,互不影响。但实际上al和bl是一个对象,结果A和B共用代码classALongpublicvoidsynchronized(al)//省略代码无 8classBLongpublicsetBY(){synchronized(bl)//省略代码无}}}使用Immutability在使用Immutability模式的时候,需要注意以对象的所有属性都是final的,并不能保证不可变不可变对象也需要正确发Java言中,final饰的属性一旦被赋值,就不可以再修改,但是如果属性的类型是普通对象,那么这个普通对象的属性是可以被修改的。例如下面的代码中,Bar的属性foo虽然是final的,依然可以通过setAge()方法来设置foo的属性age。所以,在使用Immutability模式的时候一定要确认保持不变性的边界在哪里,是否要求属性对象也具备代码classintint45finalclassBar6finalFoo7voidsetAge(int89}}着这些不可变对象的对象就是线程安全的。例如在下面的代码中,Foo具备不可变性,线程安全,但是类Bar并不是线程安全的,类Bar中持有对Foo的foo,对这个的修改在多线程中并不能保证可见性和原子性代//Foo线程finalclassfinalintfinalint5//Bar线程不安classBar8Foo9voidsetFoo(Foo}}如果你的程序仅仅需要foo保持可见性,无需保证原子性,那么可以将foo为volatile变量,这样就能保证可见性。如果你的程序需要保证原子性,那么可以通过原子类决了不可变对象的原子性问题。代码publicclassSafeWMclassfinalintfinalintWMRange(intupper,int//省略构造函数实} finalrf=newnew //设置库存上voidsetUpper(intWMRangeor=//检查参if(v<thrownew WMRangenr=WMRange(v, pareAndSet(or, 28利用Immutability模式解决并发问题,也许你觉得有点陌生,其实你天天都在享受它的战果。Java语言里面的String和Long、Integer、Double等基础类型的包装类都具备不可变性,这些对象的线程安全性都是靠不可变性来保证的。Immutability模式是最简单的解决并发问题的方法,建议当你试图解决一个并发问题时,可以首先尝试一下Immutability具备不变性的对象,只有一种状态,这个状态由对象内部所有的不变属性共同决定。其实还有一种更简单的不变性对象,那就是无状态状态的对象,你可能还听无状态的服务、无状态的协议等等。无状态有很多好处,最核心的一点就是性能。在多线程领域,无状态对象没有线程安全问题,无需同步处理,自然性能很好;在分布式领域,无状态意味着可以无限地水平扩展,所以分布式领域里面性能的瓶颈一定不是出在无状态的服务节点上。下面的示例代码中,Account属性是final,并且只有get法,那这个类是不是具代码1publicfinalclass2private3StringBuffer4publicAccount(String5this.user6new7}89publicStringBufferreturn}publicStringreturn}} 科技所有 不 售卖。页面已增加防盗追踪,将依 其上一 27|并发工具类模块热点问题答下一 29|Copy-on-Write模式:不是延时策略的言精选留言言 18final读的",类的属性如果是型,该属性对应的类也需要满足不可变类的条件,且不能提供修改展张天 榣山樵客 4这段代码应该是线程安全的,但它不是不可变模式。StringBuffer只是字段不可变,值展作者回复:对象正在输 final 1//Foo线程安全 Foo{finalintfinalint展炎 展作者回复:感谢一路相伴 1不是不可变的,user展陈华 展 炎 staticclassLongCache{…展 finalStringBufferStingBuffer是类型,当我们说它finalStingBufferuser不可变时,实际上说的是它useruser对象,通过subappend展作者回复:易儿 publicfinalclassTestpublicstaticvoidmain(String[]args)Accoun
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中图版历史七年级上册第14课《两汉科技与文化》听课评课记录
- 八年级政治下册第五单元我是中国公民5.2《公民的权利和义务》活动探究型听课评课记录(粤教版)
- 七年级数学上册第3章实数3.1平方根听评课记录(新版浙教版)
- 人教版道德与法治八年级下册3.1《公民基本权利》听课评课记录
- 粤教版地理七年级下册7.5《日本》听课评课记录2
- 教科版道德与法治九年级上册第十课《走向小康》听课评课记录
- 冀教版数学九年级上册26.4《解直角三角形的应用》听评课记录
- 人教版七年级数学下册9.3.1《解一元一次不等式组》听评课记录
- 湘教版数学九年级下册2.3《垂径定理》听评课记录
- 人教版地理七年级下册《第二节 东南亚》听课评课记录3
- 妇科恶性肿瘤免疫治疗中国专家共识(2023)解读
- 2024年浪潮入职测评题和答案
- 小班数学《整理牛奶柜》课件
- 皮肤感染的护理诊断与护理措施
- 中考语文真题双向细目表
- 2024年江苏省对口单招英语试卷及答案
- 药品集采培训课件
- 高中物理考试成绩分析报告
- 部编版小学语文三年级上册同步练习试题含答案(全册)
- 血性胸水的护理课件
- 医共体人财物管理系统需求说明
评论
0/150
提交评论