Java并发 -- 面向对象

栏目: 后端 · 前端 · 发布时间: 4年前

内容简介:value为下面代码忽略了约束条件:即库存下限要
  1. 面向对象思想里面有一个很重要的特性: 封装
  2. 封装:将 属性实现细节 封装在 对象内部 ,外部对象只能通过目标对象的 公共方法间接访问 目标对象的内部属性
  3. 利用 面向对象 思想写 并发程序 的思路:将 共享变量 作为 对象属性 封装在内部,对 所有公共方法 制定 并发访问策略

Counter

value为 共享变量 ,作为Counter的 实例属性 ,将get()和addOne()声明为 synchronized方法 ,Counter就是一个 线程安全 的类

public class Counter {
    private long value;

    public synchronized long get() {
        return value;
    }

    public synchronized long addOne() {
        return ++value;
    }
}

不可变的共享变量

  1. 实际场景中,会有很多共享变量,如银行账户有卡号、姓名、身份证、信用额度等,其中卡号、姓名和身份证是不会变的
  2. 对于 不可变的共享变量 ,可以使用 final 关键字修饰,从而 避免并发问题

识别共享变量间的约束条件

  1. 共享变量间的 约束条件 决定了 并发访问策略
  2. 场景:库存管理中有个 合理库存 的概念,即库存有一个 上限 和一个 下限

忽略约束条件

下面代码忽略了约束条件:即库存下限要 小于 库存上限

public class SafeWM {
    // 库存下限
    private final AtomicLong lower = new AtomicLong(0);
    // 库存上限
    private final AtomicLong upper = new AtomicLong(0);

    // 设置库存下限
    public void setLower(long v) {
        lower.set(v);
    }

    // 设置库存上限
    public void setUpper(long v) {
        upper.set(v);
    }
}

存在竟态条件

public class SafeWM {
    // 库存下限
    private final AtomicLong lower = new AtomicLong(0);
    // 库存上限
    private final AtomicLong upper = new AtomicLong(0);

    // 设置库存下限
    public void setLower(long v) {
        // 检验参数合法性
        if (v > upper.get()) {
            throw new IllegalArgumentException();
        }
        lower.set(v);
    }

    // 设置库存上限
    public void setUpper(long v) {
        // 检验参数合法性
        if (v < lower.get()) {
            throw new IllegalArgumentException();
        }
        upper.set(v);
    }
}
  1. 上述代码存在 竟态条件
  2. 假设库存的下限和上限分别为2和10,线程A调用setUpper(5),线程B调用setLower(7)
  3. 线程A和线程B并发执行的结果可能是(7,5), 不符合约束条件

使用管程

public class SafeWM {
    // 库存下限
    private final AtomicLong lower = new AtomicLong(0);
    // 库存上限
    private final AtomicLong upper = new AtomicLong(0);

    // 设置库存下限
    public synchronized void setLower(long v) {
        // 检验参数合法性
        if (v > upper.get()) {
            throw new IllegalArgumentException();
        }
        lower.set(v);
    }

    // 设置库存上限
    public synchronized void setUpper(long v) {
        // 检验参数合法性
        if (v < lower.get()) {
            throw new IllegalArgumentException();
        }
        upper.set(v);
    }
}

制定并发访问策略

  1. 避免共享 :ThreadLocal + 为每个任务分配独立的线程
  2. 不变模式 :Java领域应用得很少
  3. 管程和其它同步工具 :管程是万能解决方案,但针对特定场景,使用JUC提供的读写锁、并发容器等同步 工具 性能会更好

宏观原则

  1. 优先使用成熟的工具类 (JUC)
  2. 尽量少使用低级的同步原语 (synchronized、Lock、Semaphore)
  3. 避免过早优化

转载请注明出处:http://zhongmingmao.me/2019/05/01/java-concurrent-object-oriented/

访问原文「Java并发 -- 面向对象」获取最佳阅读体验并参与讨论


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

海量运维、运营规划之道

海量运维、运营规划之道

唐文 / 电子工业出版社 / 2014-1-1 / 59.00

《海量运维、运营规划之道》作者具有腾讯、百度等中国一线互联网公司多年从业经历,书中依托工作实践,以互联网海量产品质量、效率、成本为核心,从规划、速度、监控、告警、安全、管理、流程、预案、考核、设备、带宽等方面,结合大量案例与读者分享了作者对互联网海量运维、运营规划的体会。 《海量运维、运营规划之道》全面介绍大型互联网公司运维工作所涉及的各个方面,是每个互联网运维工程师、架构师、管理人员不可或......一起来看看 《海量运维、运营规划之道》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码