前言

下面简单总结学习Java并发的笔记,关于如何利用面向对象思想写好并发程序的建议。面向对象的思想和并发编程属于两个领域,但是在Java中这两个领域却可以融合到一起。在Java语言中,面向对象编程的思想能够让并发编程变得更加简单。下面将从封装共享变量、识别共享变量间的约束条件和制定并发访问策略三方面介绍如何使用面向对象思想去指导编写并发程序。

封装共享变量

在并发编程中,格外关心的一个重点便是多线程对共享变量的访问问题。我们需要控制好对共享变量的访问接口。面向对象就有一个非常好的特性:封装(将属性和实现细节封装在对象内部),外界只能通过目标对象提供的公共方法来间接访问这些内部属性。使用面向对象的这个特性,就可以非常轻松地掌控共享变量的访问路径。

利用面向对象思想编写并发程序的思路:将共享变量作为对象属性封装在内部,对所有公共方法定制并发访问策略

例如,下面的计数器程序。计数器程序共享变量只有一个,即value,我们把它作为Counter类的属性,并且将两个公共方法get()set()声明为同步方法,这样Counter类就成为了一个线程安全的类了。

public class Counter {
private long value;
synchronized long get(){
return value;
}
synchronized long addOne(){
return ++value;
}
}

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

识别共享变量之间的约束条件十分重要,因为这会影响到并发访问策略的定制。

下面举例说明。

在库存管理中有个合理库存的概念,库存量不能太高,也不能太低,它有一个上限和一个下限。下面使用代码说明。

SafeVM中,声明了两个成员变量upperlower,分别代表了库存上限和下限,我们使用原子类AtomLong来定义这两个变量。由于原子类是线程安全的,所以这两个成员变量的set()方法就不需要同步。

public class SafeWM {
// 库存上限
private final AtomicLong upper = new AtomicLong(0);
// 库存下限
private final AtomicLong lower = new AtomicLong(0); // 设置库存上限
void setUpper(long v){
upper.set(v);
}
// 设置库存下限
void setLower(long v){
lower.set(v);
}
// 省略其他业务代码
}

但是,我们需要注意,两个共享变量之间是有一个约束条件的:库存下限要小于库存上限

于是我们就要加入参数校验,我们在方法setUpper()和方法setLower()中加入检验语句:

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

看似上面的代码没有什么问题,但是仔细分析一下,便可以发现其实存在竞态条件。(校验的结果依赖线程的执行顺序)

例如,库存初始的上限和下限分别为(2,10)。线程 A 调用 setUpper(5) 将上限设置为 5,线程 B 调用 setLower(7) 将下限设置为 7。线程A和线程B同时执行,会发现线程A和线程B都可以同时通过校验,导致最终库存为(7,5)。

线程A执行时,下限还没有被线程 B 设置,还是 2,而 5>2;线程B执行时,上限还没有被线程 A 设置,还是 10,而 7<10。

在没有识别出库存下限要小于库存上限这个约束条件之前,我们制定的并发访问策略是利用原子类,但是这个策略,完全不能保证库存下限要小于库存上限这个约束条件。

所以,在设计阶段,我们一定要识别出所有共享变量之间的约束条件,如果约束条件识别不足,很可能导致制定的并发访问策略南辕北辙。

制定并发访问策略

指定并发访问策略,从方案思想上来看,可以从以下三个方面入手:(在前一篇博客的小结中也提到过)

  1. 避免共享

    上篇文章介绍的线程封闭技术。

  2. 不变模式

    例如Actor模式,CSP模式以及函数式编程的基础都是不变模式。

  3. synchronized同步机制和并发容器

除了以上方案思想,还有一些宏观原则需要了解。

  1. 优先使用成熟的工具类

    使用已经设计好的工具类,避免重复造轮子。

  2. 迫不得已才使用低级的同步原语

    低级的同步原语主要指的是 synchronizedLockSemaphore 等,虽然看上去简单,但使用起来还是要万分小心。

  3. 避免过早优化

    先保证线程安全性,再考虑优化性能。

小结

主要是学习参考[1]时的学习总结笔记,没有加入太多自己的思考或者补充点,(◞‸◟ )积累还不够。

要好好撸起袖子加油干!( ̄^ ̄)ゞ

参考:

[1]极客时间专栏王宝令《Java并发编程实战》

【Java并发基础】利用面向对象的思想写好并发程序的更多相关文章

  1. C#基础第七天-作业答案-利用面向对象的思想去实现名片-动态添加

    class Card { private string name; public string Name { get { return name; } set { name = value; } } ...

  2. C#基础第七天-作业-利用面向对象的思想去实现名片-动态添加

    1.利用面向对象的思想去实现: (增加,修改,删除,查询,查询全部)需求:根据人名去(删除/查询).指定列:姓名,年龄,性别,爱好,电话. 多条添加 , 动态添加 名片 本系列教程: C#基础总结之八 ...

  3. C#基础第六天-作业-利用面向对象的思想去实现名片

    1.利用面向对象的思想去实现: (增加,修改,删除,查询,查询全部)需求:根据人名去(删除/查询).指定列:姓名,年龄,性别,爱好,电话. 本系列教程: C#基础总结之八面向对象知识点总结-继承与多态 ...

  4. C#基础第六天-作业答案-利用面向对象的思想去实现名片

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 2018.3.5 Java语言基础与面向对象编程实践

    Java语言基础与面向对象编程实践 第一章 初识Java 1.Java特点 http://www.manew.com/blog-166576-20164.html Java语言面向对象的 Java语言 ...

  6. 黑马程序员——OC语言基础语法 面向对象的思想

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结)(一)基础语法 1)关键字 @interface.@implementati ...

  7. python基础----以面向对象的思想编写游戏技能系统

    1. 许多程序员对面向对象的思想都很了解,并且也能说得头头是道,但是在工作运用中却用的并不顺手. 当然,我也是其中之一. 不过最近我听了我们老师的讲课,对于面向对象的思想有了更深的理解,今天决定用一个 ...

  8. C语言用面向对象的思想写贪吃蛇

    大概一年前这时候,接触C语言一个月,那时候知之甚少,对面向对象只觉”可远观而不可亵玩“,而且会看到很多言论说C语言就是面向过程的语言,C++就是面向对象的语言.不过,不记得什么时候在网上看到过一篇博文 ...

  9. 2018.6.20 Java考试试题总结(Java语言基础与面向对象编程)最新版

    Java考试试题总结 一.单选题(每题1分 * 50 = 50分) 1.java程序的执行过程中用到一套JDK工具,其中javac.exe指( B ) A.java语言解释器 B.java字节码编译器 ...

随机推荐

  1. docker安装启动、配置MySql

    1.安装mysql镜像 docker pull mysql/mysql-server 2.docker中启动Mysql容器 docker run --name mysql01 -d -p 3306:3 ...

  2. Python爬虫之Beautifulsoup模块的使用

    一 Beautifulsoup模块介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Be ...

  3. centos6.x将python2.6升级到2.7

    一,安装开发工具和Python2.7(1)查看当前python版本 python -V Python 2.6.6 (2)下载Python-2.7.3 wget http://python.org/ft ...

  4. 《面试宝典》 2019年springboot面试高频题(java)

    前言 2019年已经成为了过去,借此机会想好好总结一下2019年项目研发的成效,看看在项目从无到有,都经历了那些变化?取得了哪些成果?踩过哪些坑?一个人.一个研发团队要想有质的飞跃,必须善于反思过去, ...

  5. .NET 半天搭建Jenkins持续集成与自动化部署系统

    前言 相信每一位程序员都经历过深夜加班上线的痛苦!而作为一个加班上线如家常便饭的码农,更是深感其痛.由于我们所做的系统业务复杂,系统庞大,设计到多个系统之间的合作,而核心系统更是采用分布式系统架构,由 ...

  6. 基础之Lamada和Stream的邂逅

    show me the code and take to me,做的出来更要说的明白 GitHub项目JavaHouse同步收录 喜欢就点个赞呗! 你的支持是我分享的动力! 引入 是否有遇到看不懂身边 ...

  7. 斜率优化入门题题单$QwQ$

    其实就是这一篇的那个例题帕的大部分题目的题解就写这儿辣,,, 因为都是些基础题不想专门给写题解,,,但是又掌握得差不得不写,,, 麻油办法就写一块儿好辣$QwQ$ 当然辣比较难的我就没放进来辣$QwQ ...

  8. Theia——云端和桌面版的IDE

    Theia是一个利用最新的web技术开发的支持云端和桌面运行的类似IDE的产品,它是一个可扩展的平台,并且全面支持多语言. 目标 建立一个可搭建类似IDE产品的平台 为终端用户提供完整的多语言IDE( ...

  9. 「学习笔记」动态规划 I『初识DP』

    写在前面 注意:此文章仅供参考,如发现有误请及时告知. 更新日期:2018/3/16,2018/12/03 动态规划介绍 动态规划,简称DP(Dynamic Programming) 简介1 简介2 ...

  10. 设置文本框的 placeholder 的颜色

    使用方法: 选择器类型::-webkit-input-placeholder input::-webkit-input-placeholder{ color:rgba(144,147,153,1); ...