6基础知识笔记二

安全的对象构造过程

不要在构造过程使用this引用逸出。

可以使用工厂方法来防止this引用在构造过程中逸出。

public class SafeListener{
	private final EventListener listener;
	
	private SafeListener(){
		listener = new EventListener(){
			public void onEvent(Event e){
				doSomething(e);
			}
		};
	}
	
	public static SafeListener new Instance(EventSource source){
		SafeListener safe = new SafeListener();
		source.registerListener(safe.listener);
		return safe;
	}
}
这里没有看明白为什么使用了私有的构造方法就能避免this引用逸出了?个人觉得这样照样可以在里面使用this引用,一时还没有想明白。

线程封闭

如果仅在单线程内访问数据,就不需要同步。这种技术被称为线程封闭,它是实现线程安全最简单的方式之一。

有三种线程封闭方式:Ad-线程封闭、栈封闭、ThreadLocal类。

Ad-线程封闭是指,维护线程封闭性的职责完全由程序实现了承担。

栈封闭式线程封闭的一种特例,在栈封闭中,只能通过局部变量才能访问对象。如果在线程内部上下文中使用非线程安全的对象,那么该对象仍然是线程安全的。

ThreadLocal类是维持线程封闭性的一种更规范方法。ThreadLocal提供了get与set等访问接口或方法,这些方法都为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当前执行线程在调用set时设置的最新值。ThreadLocal对象通常用于防止对可变的单实例变量或全局变量进行共享。

private static ThreadLocal<Connection> connectionHolder
	= new ThreadLocal<Connection>(){
		public Connection initialValue(){
			return DriverManager.getConnection(DB_URL);
		}
	};

public static Connection getConnection(){
	return connectionHolder.get();
}


不变性

如果某个对象在被创建后其状态就不能被修改,那么这个对象就被称为不可变对象。不可变对象一定是线程安全的一个对象所有的域都声明为final类型的,这个对象也仍然是可变的,因为final类型的域可以保存可变对象的引用

当满足以下条件时,对象才是不可变的:

  1. 对象创建后其状态不能被修改。
  2. 对象所有域都是final类型的。
  3. 对象是正确创建的(在对象的创建期间,this引用没有逸出)。
如果类有任何可变对象引用,那么当它们在类和类的调用者间传递的时候必须保护性拷贝。

Final域
final类型的引用变量指向的引用对象,是不能重新指向其它的引用对象。final域能确保初始化过程的安全性,从而不受限制被访问,在共享对象时无须同步。

安全发布
对象安全地发布:
  • 在静态初始化函数中初始化一个对象引用。
  • 将对象的引用保存到volatile类型的域或者AtomicReferance对象中。
  • 将对象的引用保存操某个正确构造对象的final类型域中。
  • 将对象的引用保存到一个由锁保护的域中。
事实不可变对象
如果对象从技术上来看是可变的,但其状态在发布后不会再改变,那么把这种对象称为“事实不可变对象”。
在没有额外的同步的情况下,任何线程都可以使用被安全发布地事实不可变对象。

对象的发布需求取决于它的可变性:
  • 不可变对象可以通过任意机制来发布。
  • 事实不可变对象必须通过安全机制来发布。
  • 可变对象必须通过安全机制来发布,并且是线程安全的或者由某个锁保护起来。
在并发程序中使用和共享对象时,可以使用一些实用的策略,包括:

线程封闭。

只读共享。

线程安全共享。线程安全的对象内部实现同步。

保护对象。线程通过获得锁来访问。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值