博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java并发编程实战------阅读笔记第三章
阅读量:7177 次
发布时间:2019-06-29

本文共 2400 字,大约阅读时间需要 8 分钟。

hot3.png

1、不要在构造过程中使this引用逸出。当且仅当对象的构造函数返回时,对象才处于可预测和一致的状态,当从对象的构造函数中发布对象时,只是发布了一个尚未构造完成的对象。只有当构造函数返回时,this引用才应该从线程中逸出,构造函数可以将this引用保存到某个地方,只要其他线程不会在构造函数之前使用它。如果想在构造函数中注册事件监听器或者启动线程,可以使用一个私有的构造函数和公共的工厂方法。

public class SafeListener {		private final EventListener listener;		private SafeListener(){		listener = new EventListener(){			public void onEvent(Event e){				//TODO			}		};	}		public static SafeListener newInstance(EventSource source){		SafeListener safe = new SafeListener();		source.registerListener(safe.listener);		return safe;	}}

2、线程封闭(Thread Confinement),JDBC中的Connection对象就使用了线程封闭技术。JDBC规范并不要求Connection是线程安全的,但是连接池将其分配给一个线程之后,到Connection返回给连接池之前,连接池不会再把该Connection分配给其他线程使用,因此相当于线程封闭了;ThreadLocal也是线程封闭的。 AD HOC线程封闭,很少用(未懂是什么)。 栈封闭:只能通过局部变量才能访问对象(局部变量被封闭在执行线程中,因此自然的封闭了)。书中的例子:

public int loadTheArk(Collection
candidates){ SortedSet
animals; int numPairs = 0; Animal candidate = 0; //animals封闭在方法中,不要使其逸出 animals = new TreeSet
(new SpecialGenderComparator()); animals.addAll(candidates); for(Animal a : animals){ if(candidate == null || !candidate.isPotentialMate(a)) candidate = a; else{ ark.load(new AnimalPair(candidate,a)); ++numPairs; candidate = null; } } return numPairs; }

线程封闭性更规范的方法:ThreadLocal,防止可变的单实例变量(Singleton)或全局变量进行共享。

private static ThreadLocal
connectionHolder = new ThreadLocal
(){ public Connection initialValue(){ Connection conn = null; try { conn = DriverManager.getConnection("URL"); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } }; public static Connection getConnection(){ return connectionHolder.get(); }

可以用来保存事务上下文,避免调用每个方法时都要传递执行上下文信息。这样也会使运用了该机制的框架代码与一般代码耦合在一起。滥用ThreadLocal类似于全局变量,降低代码可重用性,并在类之间引入隐含的耦合性。

3、不变性:不可变对象一定是线程安全的,所有的域都是final类型的,对象也未必是不可变的,因为final类型的域可以保存可变对象的引用。符合以下条件则不可变: .)对象创建以后其状态就不能修改; .)对象的所有域都是final类型; .)对象都是正确创建的(在对象创建期间,this引用没有逸出)。 “不可变的对象”与“不可变的对象引用”之间存在差异,保存在不可变对象中的程序状态依然可以更新,可通过一个保存新状态的实例来替换原有的不可变对象。 大神们说的良好变成习惯:除非需要更高的可见性,否则将所有的域都声明为私有域;除非需要某个域是可变的,否则应将其声明为final域。 可以使用指向不可变容器对象的volatile类型引用以缓存最新的结果。

4安全发布:安全发布一个对象,对象引用和对象状态必须同时对其他线程可见,一个正确构造的对象可以通过以下方式安全发布: .)在静态初始化函数中初始化一个对象引用; .)将对象的引用保存到volatile类型的域或者AtomicReferance对象中; .)将对象的引用保存到某个正确构造对象的final类型域中。 .)将对象的引用保存到一个由锁保护的域中。

转载于:https://my.oschina.net/u/2458458/blog/779172

你可能感兴趣的文章
Linux修改本地时间
查看>>
elasticsearch字符串包含查询
查看>>
5- Flask构建弹幕微电影网站-项目分析、搭建目录及模型设计
查看>>
Mysql四种常见数据库引擎
查看>>
《Kotin 极简教程》第7章 面向对象编程(OOP)(1)
查看>>
Chrome吃内存的能力可不是说着玩的!
查看>>
iStaing获500万美元投资,VR室内设计离我们还远吗?
查看>>
Java日志框架-Spring中使用Logback(Spring/Spring MVC)
查看>>
读书笔记--101个shell脚本 之#12--函数
查看>>
TCP/IP之(四)Delay ack 和 Nagle算法
查看>>
linux学习:selinux 禁用后(disabled)Linux系统无法正常启动解决
查看>>
关于tomcat和jetty对比(不喜欢jetty的勿看)
查看>>
grafana使用详解
查看>>
linux 文件同步 rsync+crontab
查看>>
git如何删除远程仓库的某次错误提交
查看>>
LAMP架构讲解(续一)
查看>>
linux下查看文件编码及修改编码
查看>>
VC中的延时
查看>>
算法与数据结构知识点
查看>>
在单位成功实验的PIX配置
查看>>