1、设计线程安全类的过程

设计线程安全类的过程就是设计对象状态并发访问下线程间的协同机制(在不破坏对象状态变量的不变性条件的前提下)。

(1)构建线程安全类的三个基本要素:

1)找出构成对象状态的所有变量;(确定状态变量的类型(共享、可变的、不可变的),针对不同类型的状态变量采用不同的并发访问策略)

2)找出约束对象状态变量的不变性条件;(不变性条件本质上就是确定状态变量自身的约束条件和状态变量间的依赖关系)

对象状态变量的不变性条件与后验条件约束了在对象状态上有哪些状态和状态转换是有效的,也就是对象状态变量的值哪些是有效的,哪些状态之间的转换时有效的,而哪些状态变量值和哪些状态间的转换时无效的。

3)建立对象状态的并发访问管理策略

同步策略:定义了如何在不违背不破坏对象不可变性或后验性的情况下对其状态的访问操作进行协同,规定了如何将不可变性、线程封闭、加锁机制等结合起来已维护线程的安全性,并且还规定了哪些变量由哪些锁来保护。

(2)构建线程安全类的过程

1)收集同步需求

确定构成对象状态的所有变量和对象状态变量不可变性条件的过程。

2)依赖状态的操作

在依赖对象状态的操作上(比如先验条件)如何设计,最简单的办法是通过现有库中的类来实现依赖状态的行为。

3)状态的所有权

确定状态变量如何共享和发布

2、构建线程安全类的三种方法:

(1)构建线程安全类的最简单方式:实例封闭

将数据封装在对象的内部,可以将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。

封闭机制和加锁机制结合起来,就可以确保以线程安全的方式使用非线程安全的对象

Java监视器模式:封装对象的所有可变状态,并有对象自己的内置锁来保护。

(2)组合多个类构建线程安全类(线程安全性的委托)

1)单个状态变量情况下

将单个状态变量委托给线程安全的类(如ConcurrentHashMap等)

2)多个状态变量且没有不可变性的约束下

每个状态变量都交给一个线程安全类维护

3)多个状态变量且存在不可变性的约束

委托和加锁机制联合起来才能实现在构建线程安全类的过程中不破坏多个状态变量不可变性条件。

4)发布底层的状态变量

如果一个类由多个独立且线程安全的状态变量组成,并且在所有的操作中都不含无效的状态转换,那么可以将线程安全性委托给底层的状态变量。

底层状态变量的发布:如果一个状态变量是线程安全的类,并且没有任何不变性条件来约束它的值,在变量的操作上也不存在任何不允许的状态转换,那么就可以安全的发布这个变量。

(3)在现有线程安全类中添加功能以构建新的线程安全类

1)修改现有线程安全类代码,新增功能

2)扩展现有线程安全类

3)使用辅助类扩展类的功能

4)组合

3、线程安全类的维护

将同步策略文档化

4.构建线程安全性委托的基础构建模块

(1)同步容器类

同步容器只有所有对容器状态的访问操作都串行化,才能实现他们的线程安全性。在并发的环境中,访问容器的状态在客户端没有加锁的情况下不是线程安全的。

实现线程安全的方式:封装容器的状态,把所有公有的的方法都进行同步,使得每次只有一个线程可以访问容器的状态。

缺点:严重降低并发性,吞吐量低

(2)并发容器

(1)ConCurrentHashMap

(2)CopyOnWriteArrayList

(3)阻塞队列和生产者-消费者模式

(1)BlockingQueue 阻塞队列:适用于生产者-消费者模式(消费者共享一个工作队列)

(2)BlockingDeque 阻塞双端队列:适用于工作密取模式(每个消费者都有一个自己的双端队列,当自己的双端队列完成后消费者可以从其他消费者的双端队列内获取)

工作密取模式比生产者-消费者模式更具可伸缩性,因为工作密取的每个消费者都有自己的工作队列,就减少了在因共享队列上因获取的数据而发生的竞争。

(4)阻塞方法和中断方法

(5)同步工具类

(1)CountDownLatch

(2)FutureTask

(3)Semaphore

(4)CyclicBarrier和Exchanger

(6)构建高效且可伸缩的结果缓存

那些年读过的书《Java并发编程实战》二、如何设计线程安全类的更多相关文章

  1. 《Java并发编程实战》学习笔记 线程安全、共享对象和组合对象

    Java Concurrency in Practice,一本完美的Java并发参考手册. 查看豆瓣读书 推荐:InfoQ迷你书<Java并发编程的艺术> 第一章 介绍 线程的优势:充分利 ...

  2. 读书笔记-----Java并发编程实战(一)线程安全性

    线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet @ThreadSafe public class StatelessFactorizer ...

  3. 《Java并发编程实战》第二章 线程安全性 读书笔记

    一.什么是线程安全性 编写线程安全的代码 核心在于要对状态訪问操作进行管理. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与 ...

  4. 《Java并发编程实战》第二章 线程安全 札记

    一个.什么是线程安全 编写线程安全的代码 其核心是管理国事访问的操作. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与其规范 ...

  5. java并发编程实战:第二章----线程安全性

    一个对象是否需要是线程安全的取决于它是否被多个线程访问. 当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错.解决办法: 不在线程之间共享该变量 将状态变量修改为不可变的 在访问 ...

  6. Java并发编程实战 第8章 线程池的使用

    合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...

  7. Java并发编程实战(5)- 线程生命周期

    在这篇文章中,我们来聊一下线程的生命周期. 目录 概述 操作系统中的线程生命周期 Java中的线程生命周期 Java线程状态转换 运行状态和阻塞状态之间的转换 运行状态和无时限等待状态的切换 运行状态 ...

  8. Java 并发编程(三)为线程安全类中加入新的原子操作

    Java 类库中包括很多实用的"基础模块"类.通常,我们应该优先选择重用这些现有的类而不是创建新的类.:重用能减少开发工作量.开发风险(由于现有类都已经通过測试)以及维护成本.有时 ...

  9. 《Java并发编程实战》第八章 线程池的使用 读书笔记

    一.在任务与运行策略之间的隐性解耦 有些类型的任务须要明白地指定运行策略,包含: . 依赖性任务.依赖关系对运行策略造成约束.须要注意活跃性问题. 要求线程池足够大,确保任务都能放入. . 使用线程封 ...

  10. Java并发编程(十)设计线程安全的类

    待续... 线程安全的类 之前学了很多线程安全的知识,现在导致了我每次用一个类或者做一个操作我就会去想是不是线程安全的.如果每次都这样的考虑的话就很蛋疼了,这里的思路是,将现有的线程安全组件组合为更大 ...

随机推荐

  1. PWDX查找程序执行路径

    PWDX通过PID号查找文件对应的启动目录 在linux 64位 5.4及SunOS 5.10上测试通过 通常的做法: [root@app1 bin]# ps -ef | grep java root ...

  2. .net core实现跨域

    什么是跨域在前面已经讲解过了,这里便不再讲解,直接上代码. 一.后台API接口 用.net core创建一个Web API项目负责给前端界面提供数据. 二.前端界面 建立两个MVC项目,模拟不同的ip ...

  3. [原创]找不到mswinsck.ocx的解决办法

    mswinsck.ocx,是在运行程序或者游戏时,系统弹出错误提示“ 找不到mswinsck.ocx”,或者“ 没有找到 mswinsck.ocx”时,说明您系统中缺失这个OCX文件或者该OCX文件没 ...

  4. DOS、Mac 和 Unix 文件格式+ UltraEdit使用

    文件格式 区分DOS.Mac 和 Unix分别对应三种系统 从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种 文件模式 区分ASCII模式和Binary模式  通常由系统决定,大多数 ...

  5. swoole Tcp

    TCP服务对象 <?php //创建Server对象,监听 127.0.0.1:9501端口 $serv = ); //监听连接进入事件 $serv->on('connect', func ...

  6. [Optimization] Advanced Dynamic programming

    这里主要是较为详细地理解动态规划的思想,思考一些高质量的案例,同时也响应如下这么一句口号: “迭代(regression)是人,递归(recursion)是神!” Video series for D ...

  7. Mercurial (hg) Hook : PHP Syntax Check , hg 代码检测 钩子

    用百度搜了一遍hg的hook教程,发现真的是太少了.公司目前正要用到这个,正好本人负责,So. 百度是个坑,少有的几篇文章,再加上善于发现的眼睛,发现TortoiseHg的UI操作都会在控制台显示动作 ...

  8. Oracle迁移至PostgreSQL工具之Ora2Pg

    1. 描述 Ora2Pg是一个免费的工具,用于将Oracle数据库迁移到PostgreSQL兼容的模式.它连接您的Oracle数据库,自动扫描并提取它的结构或数据,然后生成可以装载到PostgreSQ ...

  9. php info

    http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/08/12/1797753.html  php pdo 相关 http://blog.cs ...

  10. 解决 Spring Oauth2 RedisTokenStore storeAccessToken 报错 java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.set

    原因是Spring 版本兼容问题 参考: https://blog.csdn.net/smollsnail/article/details/78954225 继承 RedisTokenStore 修改 ...