美文网首页
用不变对象解决竞态问题

用不变对象解决竞态问题

作者: 吃番茄的土拨鼠 | 来源:发表于2018-05-11 16:35 被阅读0次

不可变对象

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

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

对于不可变对象, 需要防止发生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;

        }  

    }  

}  

相关文章

  • 用不变对象解决竞态问题

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

  • golang 互斥锁

    1,竞态的出现原因 竞态的产生是因为多个对象同时访问一个对象的时候就会产生。 最常见的例子是数据库。 在开发中多线...

  • Guava_集合篇

    关于不可变集合 当对象被不可信的库调用时,不可变形式是安全的; 不可变对象被多个线程调用时,不存在竞态条件问题 不...

  • 【链安】竞态条件漏洞分析及详细修复建议

    什么是竞态条件 【竞态条件】竞态条件的官方定义是如果程序的执行顺序改变会影响结果,它就属于一个竞态条件。在智能合约...

  • 如何解决并发导致的竞态问题

    1. 中断屏蔽 相关函数 local_irq_disable() local_irq_enable() local...

  • 屏幕适配

    用简单的语言解决我们开发过程中的屏幕适配问题: 1.保持对象的frame位置的x与y值不变 2.根据不同的屏幕尺寸...

  • WWDC 2016 Thread Santizer and St

    一. Thread Santizer(TSAN) 线程竞态检测工具:可以在运行时发现线程竞态 竞态 两个线程同时访...

  • Java并发

    无状态对象一定是线程安全的 竞态条件当某个计算的正确性取决于多个线程的交替执行时序时,那么久会发生竞态条件。换句话...

  • redux 解决竞态的方式

  • 建造者模式

    它有啥用 它用于解决,通过变化无常的方式,来组织相对不变的构成要素,形成一个整体对象的问题。再强调一遍,变化的是方...

网友评论

      本文标题:用不变对象解决竞态问题

      本文链接:https://www.haomeiwen.com/subject/ofafdftx.html