JAVA虚拟机并发编程读书笔记——第一部分 并发策略 第3章 设计方法

设计方法
操纵状态并不一定意味着改变状态。考虑用状态转换来代替修改状态,这是一种无需修改任何东西就能改变状态的设计方法。在本意中,我们将会研究无需更改内存中任何数据的程序设计方法。本意函盖了很多设计的基础方法。

处理状态:
1.共享可变性 share mutability
2.隔离可变性 isolated mutability
3.纯粹不可变性 pure inmutability

在一个JAVA用户组会议上,提出想把所有与会人员的工龄进行一下汇总。
共享可变性:
对totoal进行访问进行同步 过多的线程阻塞,耗时长
隔离可变性:
每个人把工龄发给我短信,总工龄由我来加,只有我可以访问
纯粹不可变性设计:
所有人组成一条人链,让每个人接收左边那个人的工龄值,将自己的工龄累加到那个值上,并将累加值传递给自己右边的人

持久的/不可变的数据结构
我们使用不可变的或持久化的结构来解决大对象的拷贝问题。
持久化数据结构将其值按版本进行记录,所以新老数据可以并存或保持一段时间而不会降低程序性能。由于数据是不可变的,所以可以将数据共享出去,以便有效地避免拷贝所产生的代价,可以提供超高效的更新操作。

不可变链表:高效的增加和删除
采用头插法在不可变链表增加新结点,新结点的第二个引用将指向当前链表的头部,这样就可以在不修改已有链表的情况下得到一个新的链表,添加操作仅需常数时间且与链表长度无关

持久化的Tries
Trie结构:
1)高分去因子:每个节点至少饱含32个子结点,高分去因子可以有效减少对于trie结构的操作时间。
2)节点key:节点的key是由其路径决定的。 不用保存key,结点的位置可以作为key。
分支路径为100,十进制为9。 1*3^2 + 0 *3^1 + 0 3^0 = 9
分支路径为11,十进制为4。 1
3^1 + 1 *3^0 = 4

对树的改动可以简化为对该树一个分支的改动。
一个分支因子为32的trie结构至多用4层就可以保存一百万个元素,而更改其中任意元素至多需要拷贝4个元素。即插入路径上的所有节点均需要拷贝并实现,这已经近似于常数时间了。
可以用来实现多种不同的数据结构,如树,hashmap和链表等。不可链表只可以在头部插入和删除,trie结构可以在任意索引处插入和删除元素。

插入一个元素:浅拷贝待插入节点的祖先,只拷贝指针不拷贝数据。将元素插入到trie的任意索引位置将会比标准插入代价更高。因为根据插入位置不同,我们将会需要一些额外的部分拷贝来完成插入操作。

选择一种设计方法:
我们可以通过使用隔离可变性方法和纯粹不可变方法来避免大多数并发问题。大多数情况下,使用隔离可变性方法比使用纯粹不可变性方法在编程方面要简单得多。
如果选择了隔离可变性的方法,需要保证可变变量切实被隔离开,且绝不会被超过一个线程访问。同时还需要保证线程之间传递的消息都是不可变的。实际应用中,我们即可使用JDK提供的并发API,也可以使用任何一个基于角色的并发框架来实现消息传递。

小结:
虽然无法回避状态处理的问题,但我们还是有三种可选的设计方法:
共享可变性方法
隔离可变性方法
纯粹不可变性方法
虽然我们一直使用共享可变性方法,但应该尽量可能地去避免它。消除共享可变状态是避免同步问题的最简单途径。然而选择这些设计方法比挑选一个库或一个API更耗精力,同时也需要我们退而思考如何去设计应用程序。

下章我们将使用JDK自带的工具来进行并发程序设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值