设计线程安全的类

设计线程安全的类:

在设计线程安全类的过程中,需要包含以下三个基本要素:

  • 找出构成对象状态的所有变量;
  • 找出约束状态变量的不变性条件;
  • 建立对象状态的并发访问管理策略。

要分析对象的状态,首先从对象的域开始。如果对象中所有的域都是基本类型的变量,那么这些域将构成对象的全部状态。如果对象的域中引用了其他对象,则该对象的域包含被引用对象的域。

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

收集同步需求:

在许多类中都定义了一些不可变条件,用来判断状态是有效的还是无效的。例如long类型的变量,其状态空间是Long.MIN_VALUE到Long.MAX_VALUE。但我们定义了一个类,该类中有一个long类型的计数器,则该long类型的变量存在一个限制,即不能为负值。

同样,在操作中还会包含一些后验条件来判断状态迁移是否是有效的。如计数器当前值为17,那么下一状态只能是16或18.当下一个状态需要依赖当前状态时,这个操作就必须是一个复合操作。

由于不变性条件和后验条件在状态和状态转换上添加了与许多限制,因此就需要额外的同步和封装。

如果不了解对象的不可变条件和后验条件,那么就不能确保线程安全性。要满足各种约束条件,就需要借助于原子性与封装性。

依赖状态的操作:

类的不变性条件和后验条件约束了在对象上有哪些状态和状态转换是有效的。在某些对象的方法中还包含一些基于状态的先验条件。例如不能从空队列中删除一个元素。如果在某个操作中包含有基于状态的先验条件,那么这个操作就被称为依赖状态的操作。

线程安全性委托:

大多数对象都是组合对象。当从头开始构建一个类或者将多个非线程安全的类组合成一个类时,监视器模式非常有用。但如果类中各个组件已经是线程安全的,会是什么情况?在某些情况下通过多个线程安全类组合而成的类是线程安全的,而在某些情况下不是。

如果某个类含有复合操作,那么仅靠委托并不足以实现线程安全性。在这种情况下这个类必须提供自己的加锁机制以保证这些复合操作都是原子操作,除非整个复合操作都可以委托给状态变量。

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

发布低层的状态变量:

当把线程安全性委托给某个对象的底层状态变量时,什么条件下可以发布这些变量从而使其他类可以修改它们?答案仍然取决于在类中对这些变量施加了什么不变性条件。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

Linux下的计算命令和求和、求平均值、求最值命令梳理

在Linux系统下,经常会有一些计算需求,那么下面就简单梳理下几个常用到的计算命令 (1)bc命令 bc命令是一种支持任意精度的交互执行的计算器语言。bash内...

3417
来自专栏架构说

缓存策略之LRU实现及分析

LRU定义 Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时, 就需要挑选并舍弃原有的部分内容,从而腾出空间...

32710
来自专栏Java面试笔试题

简述synchronized 和java.util.concurrent.locks.Lock的异同?

Lock是Java 5以后引入的新的API,和关键字synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点...

1244
来自专栏有趣的Python

代码模板:python-基础-5(菲波那切数列)

选自python高效开发实战。 # -*- coding: utf-8 -*- #!/usr/bin/env python ## linux系统告诉系统pyth...

3186
来自专栏用户2442861的专栏

网易2013校园招聘笔试题详解

http://blog.csdn.net/silangquan/article/details/18142651

1302
来自专栏Echo is learning

R 数据分析

2142
来自专栏Spark学习技巧

ConcurrentHashMap实现原理

1304
来自专栏coder修行路

Nginx location 匹配顺序整理

Nginx location模块整理 具体的Nginx安装就不在这里描述了,这里只是为了对location的描述 Nginx环境 a. 查看当前系统cat /e...

3027
来自专栏决胜机器学习

《Redis设计与实现》读书笔记(二) ——Redis中的字典(Hash)

《Redis设计与实现》读书笔记(二) ——Redis中的字典(Hash) (原创内容,转载请注明来源,谢谢) 一、概述 字典,又称符号表、关联数组、映射,是一...

39010
来自专栏瓜大三哥

Verilog 模块编程要点

1) 时序电路建模时,用非阻塞赋值。 2) 锁存器电路建模时,用非阻塞赋值。 3) 用 always 块建立组合逻辑模型时,用阻塞赋值。 4) 在同一个 alw...

2126

扫码关注云+社区