如何正确的JCP
2016-03-03 09:22:37 0 举报
AI智能生成
JCP(Java Community Process)是Java社区的一个开放的协作过程,旨在推动Java技术的发展和规范。它由Java SE/EE平台、技术和工具的专家组和实现者组成,通过公开透明的讨论和决策来制定Java技术规范和标准。参与JCP需要遵守其章程和流程,包括提交提案、评审、投票等环节。JCP的目标是确保Java技术的稳定性、兼容性和可扩展性,为Java开发者提供更好的开发体验和更广泛的应用场景。
作者其他创作
大纲/内容
Java线程模型引入的风险
安全性问题(程序执行的结果可能是错误的)
不在线程间共享该状态变量
将状态变量修改为不可变的变量
在访问状态变量时使用同步
活跃性问题
死锁
饥饿
活锁
性能问题
服务时间过长
响应不灵敏
吞吐率过低
资源消耗过高
线程安全性
类的线程安全性定义:
当多个线程访问某个类时,不管运行时环境采用何种调度方式或者如何交替执行,并且在主调代码中不需要使用额外的同步或协同,这个类都能表现出正确的行为
实现线程安全性的方法:
无状态对象(只包含方法的对象)
原子性
原子操作是线程安全的
非原子操作(复合操作)引入竞态条件
定义:当某个计算的正确性取决于多个线程的交替执行时序时,就会发生。(既正确的结果取决于运气)
类型:
先检查后执行(Check-Then-Act)
读取-修改-写入
保障原子性
使用java.util.concurrent.atomic包中的原子类
使用加锁机制
使复合操作变为原子操作
保护对象状态(取值仍然需要加锁)
可能引起的问题:
活跃性
性能
3 安全的共享对象
使被修改的对象值及时可见(可见性)
原因:Java的内存模型无法保证在多线程环境下读操作线程能适时看到其他线程写入的值
问题:
失效数据
非原子的64位操作
解决方法:
加锁
内置锁
显式锁
使用volatile修饰符
安全的发布对象
概念
发布对象-使对象能在当前作用域之外的代码中使用
将对象引用保存到其他代码可访问的地方
在一个非私有方法中返回该引用
将引用传递到其他类的方法中
对象逸出-不该发布的对象被发布。
发布对象时被一起发布的成员对象
在构造函数中使this对象逸出
使用工厂方法
不在构造方法中发布内部类
正确的发布对象-对象的引用以及对象的状态同时对其他线程可见
3.5.1不安全发布对象的问题(由可见性导致):
其他线程看到的被发布对象是一个失效值
其他线程看的的被发布对象的状态(成员变量)是失效值
不可变对象即使被不正确发布,也能保证安全访问
3.5.3 安全的发布对象的方法:
在静态初始化函数中初始化一个对象的引用
将对象的引用保存到volatile类型的域或者AtomicReferance对象中
将对象的引用保存到某个正确构造对象的final类型中
将对象的引用保存到一个由锁保护的域中
实现该条的实例:
对于键值对-Hashtable, synchronizedMap, ConcurrentMap
对于元素-Vector, CopyOnWriteArrayList, CopyOnWriteArraySet, synchronizedList, synchronizedSet
BlockingQueue, ConcurrentLinkedQueue
Future, Exchanger
3.5.4 事实不可变对象-不是不可变对象,但事实上不会被其他线程修改
3.5.5不同类型对象的发布需求
不可变对象可以通过任意机制发布
事实不可变对象必须通过安全方式发布
可变对象必须通过安全方式发布,并且必须是线程安全的或者由某个锁保护起来的
不发布对象
3.3 线程封闭(不共享,对象仅供单线程使用)
Ad-hoc线程封闭
维护线程封闭性的职责由程序实现(非常脆弱)
栈封闭
只通过局部变量才能访问对象
ThreadLocal类
3.4 使用不可变对象(不变性)
对象成为不可变对象的条件:
对象创建后状态不能修改
对象的所有域都是final类型
对象是正确创建的(创建期间没有this逸出)
除非需要某个域是可变的,否则将其声明为final域
安全共享对象的策略:
线程封闭
只读共享
线程安全共享: 线程安全的对象在其内部实现同步,多个线程可以通过对象的共有接口来进行访问而不需要进一步同步
保护对象:被保护对象只能通过持有特定锁来访问。包括:
封装在其他线程安全对象中的对象。
已发布并且有特定锁保护的对象。
安全的对象组合模式
4.1 设计线程安全的类:
基本要素
找出构成对象状态的所有变量
找出约束状态变量的不变性条件
建立对象状态的并发访问管理策略
确保类的线程安全性的条件:
不变性条件
用于判断状态是否有效
后验条件
由于判断状态迁移是否有效
依赖状态的操作(先验条件)
多线程中需要使用循环或者阻塞的方法等待先验条件为真
模式:
4.2实例封闭
被封闭对象不能超出既定作用域
封闭在类的实例(私有成员)
封闭在某个作用域(局部变量)
封闭在线程内(不在多线程中共享)
优点:
最简单
锁策略选择上的灵活性
4.2.1 java监听器模式(实例封闭的Java模式)
Vector,Hashtable
4.3线程安全性的委托
类的线程安全性委托给可变域的线程安全性
前提条件:类是由多个独立且线程安全的状态变量组成,且所有操作不包含无效状态转换
发布状态变量:
该变量线程安全
没有任何不变性条件约束它的值
不存在任何不允许的状态转换
4.4 在现有的线程安全类中添加功能
直接修改源代码(安全,但通常无法做到)
扩展这个类(继承,脆弱,破坏同步策略的风装性)
扩展类的功能(提供帮助类,在帮助类中同步,脆弱,破坏同步策略的风装性)
组合
4.5 同步策略文档化
设计同步策略需考虑的方面:
哪些变量声明为volatile
哪些变量用锁保护
哪些锁保护哪些变量
哪些变量必须是不可变的或者被封装在线程中的
哪些操作必须是原子操作
5 基础构建模块
同步容器类(每次只有一个线程能访问容器的状态)
问题:
某些情况下可能需要额外的客户端加锁来保护复合操作
迭代
5.2.1 迭代器抛出ConcurrentModificationException
加锁
克隆,在副本上迭代
5.1.3 隐藏的迭代器
容器的toString方法
hashCode
跳转
条件运算
并发容器
使用并发容器代替同步容器可以极大提高伸缩性并降低风险
分支主题 4
分支主题 5
分支主题 6
分支主题 7
分支主题 8
0 条评论
下一页