java并发编程实战:第四章----对象的组合
一、设计线程安全的类
- 找出构造对象状态的所有变量(若变量为引用类型,还包括引用对象中的域)
- 约束状态变量的不变性条件
- 建立对象状态的并发访问管理策略(规定了如何维护线程安全性)
1、收集同步需求(找出复合操作、多个变量遵循原子性的操作等)
2、依赖状态的操作(找出操作是否基于先验条件,例:取出当队列不为空)
3、状态的所有权(对象被哪些线程所有,哪些线程可以操作对象)
二、实例封闭
将数据封装在对象内部,可以将数据的访问限制在对象的方法上,确保简单正确的持有锁。(因为无需观察整个程序,只需检查当前类)
Java提供包装器对ArrayList、HashMap等容器对象提供线程安全保护
1、Java监视器模式:把对象的所有可变状态封装起来,并使用对象的内置锁保护
使用私有锁而不是内置锁的优点:(private final Object myLock = new Object();)
- 私有锁可以将锁封装起来,客户代码无法得到锁
- 客户可以通过公有方法来访问锁,以便参与到同步策略中去。
2、实例:基于监视器模式的车辆追踪

MutablePoint不一定是线程安全的,但该类一定是线程安全的,因为它包含的Map对象与Map中的Point对象都未曾发布,并且满足实例封闭。
三、线程安全性的委托
通过多个线程安全的类组成的类不一定是线程安全的
委托:通过委托类的线程安全性判断被委托类的线程安全性
1、委托给单个线程安全状态变量可以保证线程安全性
2、委托给多个相互独立的线程安全状态变量可以保证线程安全性
3、如果类包含多个线程安全状态变量的符合操作,则无法保证线程安全性,可以通过加锁机制保证
4、发布:如果一个状态变量是线程安全的,并且没有不变性条件约束它(例:大于0),在变量操作上没有不允许的状态转换,则可以安全发布
5、安全发布底层状态的线程安全类
1 @ThreadSafe
2 public class PublishingVehicleTracker {
3 private final Map<String, SafePoint> locations;
4 private final Map<String, SafePoint> unmodifiableMap;
5
6 public PublishingVehicleTracker(Map<String, SafePoint> locations) {
7 this.locations = new ConcurrentHashMap<String, SafePoint>(locations);
8 this.unmodifiableMap = Collections.unmodifiableMap(this.locations);
9 }
10
11 public Map<String, SafePoint> getLocations() {
12 return unmodifiableMap;
13 }
14
15 public SafePoint getLocation(String id) {
16 return locations.get(id);
17 }
18
19 public void setLocation(String id, int x, int y) {
20 if (!locations.containsKey(id))
21 throw new IllegalArgumentException("invalid vehicle name: " + id);
22 locations.get(id).set(x, y);
23 }
24 }
四、现有的线程安全类中添加功能
例:在Vector中添加”若没有则添加“功能,可以使用拓展的办法,BetterVector继承至Vector并对该符合操作通过同步机制增加原子性
1、客户端加锁机制
使用某个对象的代码时必须使用该对象本身用于保护其状态的锁,不推荐(同步的实现被分到两个不相关的类中)
当没有使用同一个锁,不足以提供线程安全保护:

2、组合
ImprovedList将List的操作委托给底层的list实例来操作,并通过自身的内置锁增加一层额外的加锁,同时添加了新的同步方法。

五、将同步策略文档化
java并发编程实战:第四章----对象的组合的更多相关文章
- Java并发编程实战 第4章 对象的组合
Java监视器模式 java监视器模式就是在将共享的数据封装在一个类里面,然后然后所有访问或者修改这些数据的方法都标注为synchronize. 车辆追踪模拟: 使用监视器模式: CarTracker ...
- Java并发编程实战 第3章 对象的共享
可见性 可见性是由于java对于多线程处理的内存模型导致的.这似乎是一种失败的设计,但是JVM却能充分的利用多核处理器的强大性能,例如在缺乏同步的情况下,Java内存模型允许编译器对操作顺序进行重排序 ...
- 【JAVA并发编程实战】2、对象的组合
1. 设计线程安全的类 1.找出构成对象状态的所有变量 2.找出约束状态变量的不变性条件 3.建立对象状态的并发访问管理策略 package cn.xf.cp.ch04; /** * *功能:JAVA ...
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- Java并发编程实战 第16章 Java内存模型
什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...
- 【java并发编程实战】第一章笔记
1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...
- Java并发编程实战 第8章 线程池的使用
合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...
- 读书笔记-----Java并发编程实战(二)对象的共享
public class NoVisibility{ private static boolean ready; private static int number; private static c ...
- JAVA并发编程实战---第三章:对象的共享(2)
线程封闭 如果仅仅在单线程内访问数据,就不需要同步,这种技术被称为线程封闭,它是实现线程安全性的最简单的方式之一.当某个对象封闭在一个线程中时,这种方法将自动实现线程安全性,即使被封闭的对象本生不是线 ...
- JAVA并发编程实战---第三章:对象的共享
在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程序中,要对内存操作的执行顺序进行判断几乎无法得到正确的结果. 非原子的64位操作 当 ...
随机推荐
- java 静态方法上的泛型
靜態方法上的泛型 泛型也可以僅定義在靜態方法上,舉例而言,在 定義與使用泛型 中自定義過支援泛型的ArrayList,如果現在想寫個asArrayList方法,可指定不定長度引數,將之轉換為Array ...
- FPGA--数字芯片之母
这个世界先有鸡还是先有蛋?没有人知道答案.但是如果有人问ess9018.ak4497.cs43198这些高端SIGMADELTA架构DAC的妈妈是谁?我们可以回答您:它们都有一个同样的妈,名字叫做FP ...
- JSTL-c:forEach标签详解
c:forEach基本格式: <c:forEach var="每个变量名字" items="要迭代的list" varStatus="每个对象的 ...
- Windows 远程桌面连接Ubuntu16.04图像界面
1.安装xrdp sudo apt-get install xrdp 2. 安装vnc4server sudo apt-get install vnc4server 3. 安装xubuntu-desk ...
- Selenium Webdriver——设置等待时间
1.隐式等待 implicitlyWait(): 当使用了隐士等待执行测试的时候,如果 WebDriver没有在 DOM中找到元素,将继续等待,超出设定时间后则抛出找不到元素的异常 当查找元素或元素并 ...
- DBNavigator中把insert变为append
procedure TForm1.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);begin if Button = nbIns ...
- Eclipse 插件集合
以下是我整理的自己开发过程中的常用Eclipse插件,按字母排序: (1) AmaterasUML 介绍:Eclipse的UML插件,支持UML活动图,class图,sequenc ...
- Yii框架操作数据库的几种方式与mysql_escape_string
一.Yii操作数据库的几种选择 1,PDO方式. $sql = "";//原生态sql语句 xx::model()->dbConnection->createComma ...
- VB指针操作和消息钩子
二.VB怎么用指针 要想弄明白VB怎么使用指针,就必须要弄明白两件事,第一,如何取得数组的指针,第二,如何将指针所指向的数组取出来. A.在讲解这两个问题之前,我们需要了解几个 ...
- nodepad++快捷键
在用notepad++进行代码编辑的过程中,其实notepad++也可以进行单行.多行.区块注释和取消注释的....... 快捷键如下: 单行.多行注释 //方式 ...