用不变对象解决竞态问题

不可变对象

所有并发问题都是由于多个线程同时访问对象的某个可变属性引起的, 如果对象是不可变的, 那么所有的并发问题都将迎刃而解. 

所谓不可变对象是指对象一旦构造完成, 其所有属性就不能更改, 不可变对象显然都是线程安全的. 

对于不可变对象, 需要防止发生this逃逸.

如果需要对多个成员进行一项原子操作, 可以考虑使用这些成员构建一个不可变类. 例如:

Java代码

publicclassCashedClass {

privateString cashedStr ="";

privateintcashedHashCode;


publicinthashCode(String str) {

// 如果str是cashedStr, 就直接返回缓存的hashCode值

if(str.equals(cashedStr)) {

returncashedHashCode;

}else{

// 将cashedStr和hashCode值缓存起来

            cashedStr = str;  

            cashedHashCode = cashedStr.hashCode();  

returncashedHashCode;

        }  

    }  

}  

CashedClass不是一个线程安全的类, 因为对cashedStr和cashedHashCode的读写操作不具备原子性, 会发生race condition. 除了使用synchronized进行同步之外, 我们还可以使用不可变对象消除race condition:

Java代码

publicclassCashedClass {

// 使用一个volatile变量持有OneCashedValue对象

privatevolatileOneCashedValue oneValue =newOneCashedValue("",0);


publicinthashCode(String str) {

inthashCode = oneValue.getStrHashCode(str);

if(hashCode == -1) {

            hashCode = str.hashCode();  

// 对volatile变量的修改不依赖于当前值, 符合volatile的使用场景

oneValue =newOneCashedValue(str, hashCode);

        }  

returnhashCode;

    }  


/**

     * 这是一个不可变类

     */

publicclassOneCashedValue {

// 成员变量都是final的

privatefinalString str;

privatefinalintstrHashCode;


// 构造过程中不会发生this逃逸

publicOneCashedValue(String str,intstrHashCode) {

this.str = str;

this.strHashCode = strHashCode;

        }  


publicintgetStrHashCode(String str) {

if(!this.str.equals(str)) {

// -1表示无效的hashCode值

return-1;

            }  

returnstrHashCode;

        }  

    }  

}  

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,495评论 11 349
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 9,171评论 0 11
  • 正值阳春三月,跟骑游群一众志同道合的朋友相约骑车踏青! 早起5点半,天也就刚刚亮,大伙陆续把车骑到了文化...
    汪曼丽阅读 1,756评论 1 1
  • 数据挖掘之优化模型 1.1数学规划模型 线性规划、整数线性规划、非线性规划、多目标规划、动态规划。 1.2微分方程...
    HeartGo阅读 6,387评论 0 5
  • 步型 夹剪步 头正颈直,微收下颊, 沉肩坠肘,上身正直放松,向下坐身,提肛溜臀,双腿屈膝, 一足在前一足在后,后足...
    时间中的看客阅读 5,731评论 0 0

友情链接更多精彩内容