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. Android自动化测试之Monkeyrunner从零开始

    最近由于公司在组织一个Free CoDE的项目,也就是由大家自己选择研究方向来做一些自己感兴趣的研究.由于之前我学过一点点关于android的东西,并且目前android开发方兴未艾如火如荼,但自动化 ...

  2. oracle转mysq遇到的问题--------1.nextval问题

    oralce里面有一个问题,在做采购单模块时,遇到如下问题: 所以我们要解决这个问题: 第一步: 并发生成方式: sequence的并发生成方式同非并发生成方式都需要建立sequence表,如下: 一 ...

  3. printf打印输出null问题的跟踪

    最近在工作中,遇到一处 printf输出有null的情况,在此记录一下,问题分析的过程. 测试代码很简单,本机为64位操作系统: #include <stdio.h> #include & ...

  4. linux dns 工具包 -- bind-utils

    https://www.cnblogs.com/274914765qq/p/4817941.html

  5. [Bayes] dchisq: Metropolis-Hastings Algorithm

    dchisq gives the density,                          # 计算出分布下某值处的密度值 pchisq gives the distribution fun ...

  6. 【代码审计】OTCMS_PHP_V2.83_代码执行漏洞分析

      0x00 环境准备 OTCMS官网:http://otcms.com 网站源码版本:网钛CMS PHP版 V2.83 [更新于2017.12.31] 程序源码下载:http://d.otcms.c ...

  7. xss攻击问题以及如何防范

    当用户提交评论的时候,比如如下评论内容 111 <scripy>alert(111);</scripy> 这样当现实评论的时候会先弹出111弹框,再显示评论.这就是xss攻击. ...

  8. Linux --Unbuntu php项目对应不同php版本

    直入主题 因服务器上项目使用php版本有不同要求,特此解决一下. 下载 服务器上已有php7.0版本,安装7.0的方法自行百度,apt-get管理工具可直接install安装 然后安装一下需要的版本. ...

  9. 评估分类器性能的度量,像混淆矩阵、ROC、AUC等

    评估分类器性能的度量,像混淆矩阵.ROC.AUC等 内容概要¶ 模型评估的目的及一般评估流程 分类准确率的用处及其限制 混淆矩阵(confusion matrix)是如何表示一个分类器的性能 混淆矩阵 ...

  10. 在Ubuntu上安装Chrome Driver和Firefox Driver

    在Ubuntu上安装Chrome Driver和Firefox Driver 此文章只介绍Chrome Driver(Firefox Driver和该步骤相同) 下载链接:http://chromed ...