Java并发 -- 面向对象

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

内容简介: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并发 -- 面向对象」获取最佳阅读体验并参与讨论


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

查看所有标签

猜你喜欢:

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

Flash ActionScript 3.0 动画高级教程

Flash ActionScript 3.0 动画高级教程

Keith Peters / 苏金国、荆涛 / 人民邮电出版社 / 2010-1 / 65.00元

《Flash ActionScript 3.0 动画高级教程》是介绍Flash 10 ActionScript动画高级技术的经典之作,是作者在这一领域中多年实践经验的结晶。书中不仅涵盖了3D、最新绘图API以及Pixel Bender等Flash 10 ActionScript特性,深入介绍了碰撞检测、转向、寻路等Flash游戏开发技术,还通过实例具体讲解了等角投影和数值积分的基本理论和应用。 ......一起来看看 《Flash ActionScript 3.0 动画高级教程》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器