Java并发编程实战(三)对象的共享

3.1 可见性

volatile关键字,将变量放在内存中,是内存的可见性,用来确保变量的更新操作通知到其他线程。这样不会出现多个线程访问变量时,变量被修改而无法感知的情况,volatile无法保证原子性。

public class NoVisblility {

	private static boolean ready;
	private static int number;
	
	private static class ReaderThread extends Thread{
		@Override
		public void run() {
			while (!ready) {
				Thread.yield();
				System.out.println(number);
			}
		}
	}
	
	public static void main(String[] args) {
		new ReaderThread().start();
		number = 42;
		ready = true;
	}
}

博主将jdk降到了1.5还是没有出现ready没有被感知的情况,(有了解的可以请告诉我~,谢谢)。


3.2 发布与逸出

发布Pulish
  指将一个指向该对象的引用保存到其他代码可以访问的地方,或将引用传递到其他类的方法中。
逸出Escape

  在对象构造完成之前就发布该对象,就会破坏线程安全性。这种情况称为逸出

public class ThisEscape {
	//隐式使this逸出 尽量不要这么做
	public ThisEscape(EventSource source) {
		source.registerListener(new EventListener() {
			@Override
			public void onEvent(Event e) {
				doSomething(e);
			}
		});
	}
}

多线程情况下对象逸出造成输出不一致,出现这种情况是因为在构造函数执行完之前都不算完成。
当且仅当对象的构造函数返回时,对象才处于可预测的和一致的状态。因此,当对象的构造函数发布对象时,只是发布了一个尚未构造完成的对象。
只有当构造函数返回时,this引用才应该从线程中逸出。构造函数可以将this引用保存到某个地方,只要其他线程不会在构造函数完成之前使用它。


为什么这样做:
1.原本的调用在多线程的情况下防止误用,告知对象的是在构造函数完成时被发布的。

2.使用safe方式写,可以完全的隐藏对象,安全的对对象进行构造,防止任何误操作。

public class SafeListener {
	private EventListener listener;
	
	private SafeListener() {
		listener = new EventListener() {
			@Override
			public void onEvent(Event e) {
				doSomething(e);
			}
		};
	}
	
	/**
	 * 只有当构造函数返回时,this引用才应该从线程中逸出。构造函数可以将this引用保存到某个地方,
	 * 只要其他线程不会在构造函数完成之前使用它。
	 */
	public static SafeListener newInsatance(EventSource source){
		SafeListener safeListener = new SafeListener();
		source.registerListener(safeListener.listener);
		return safeListener;
	}
}

3.3 线程封闭

1.Ad-hoc 线程封闭,指维护线程封闭的职责完全由程序实现来承担。Ad-hoc线程封闭技术脆弱,在程序中尽量不要使用。

2.栈封闭,是局部变量才能访问的对象,局部变量的固有属性就是封闭在执行线程中。它们位于执行线程的栈中,其他线程无法访问这个栈。

3.ThreadLocal类使线程中的某个值与保存的对象关联起来。每个使用该变量的线程都有一个独立的副本。ThreadLocal常用于防止对象可变的danbli单实例变量或全局变量进行共享。

3.4 不变性

不变性条件

  1.对象创建后的状态不可修改

  2.对象的域是final

  3.对象创建期间,this引用没有逸出

3.5 安全发布

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值