线程安全/发布

并发:一个时间段内多线程交叉执行
并行:多cpu,同一时间点,多线程同时执行
并发程序即多线程程序,即便只有一个cpu也不线程安全,如i++,A取i,调度到B取i,加1,写入,调度到A加1,写入,发生丢失更新

线程安全类:多线程访问不需客户端额外同步或协同(类里封装了同步机制),类总能表现正确行为
无状态 类一定线程安全,一个变量可考虑原子变量,两个且两个构成不变性条件呢?
多个变量的不变性条件,所有变量需同一锁保护。

同步限制重排序(试想其他线程lock后能看到本线程unlock前的操作,那么这操作不能重排到unlock后)
happens-before限制重排序(同步借助于此)
借助同步(组合多happens-before,如ReentrantLock,可对未被锁保护变量排序,对volatile state write/read 实现加锁过程中变量的可见性)
BlockingQueue (安全发布,转移对象所有权),内部同步机制保证put happens-before 时间上后面的take
happens-before扩展:线程安全容器(放,取),countdownlatch(countdown,释放),semphore(release,acquire),executor(放,执行),cyclicbarrier(达到,运行),future(set,get返回)
happens-before实现安全发布,但它比安全发布有更强可见性,顺序性(安全发布保证对象本身可见,happens-before通过程序次序提供了更强可见性,看到volatile write之前的写入)
安全初始化
静态初始化器clinit:每个线程至少加锁一次保证类已被初始化,所以任何使用静态变量线程能看到在clinit里的操作(unlock happens-before lock),但未必能看到后续的修改
对clinit扩展实现延迟初始化

private static final class Holder{
		static final Singleton3 singleton3=new Singleton3();
	}
 
	public static Singleton3 getInstance() {
		return Holder.singleton3;
	}

双重校验锁 注意用volatile引用,不使用导致情况
1未看到最新引用,进入同步代码块后看到,问题不大
2 看到引用,但看到的对象状态不对,危害很大,重排序导致对象尚未构建完成就发布了

发布 发布可能导致其他对象发布(如Set,非private域)
安全发布:其他线程能否及时看到引用,看到引用同时能否看到状态,常用下面5种方式
volatile,AtomicReference(内含volatile),锁保护域 使用先序发生规则保证及时看见引用及状态
clinit 虚拟机保护在clinit中构建对象及发布是线程安全的(有些类似双重校验锁实现单例)
对象的final域 特殊保证能看到对象状态的最新值
线程安全容器大多使用锁保护域来看到发布的对象
(线程)封闭
ad-hoc(程序完成封闭操作,很脆弱,如volatile的write放在某特定线程内)
栈封闭 使用局部变量
ThreadLocal
逸出 不该发布却发布了,构造尚未完成this引用逸出,发布内部类导致外部类引用逸出
不可变对象(创建后状态不可改变(如String的char[]本身是可变的,但我们无法对其施加改变),全final域,正确创建(无this引用逸出))一定线程安全,可任意机制发布(final 提供初始化安全性保证,once the object pointer is available to other threads, so are the correct values of that object’s final fields,我就算不能立即看到对象指针,但只要我看到了,我就能看到正确的对象状态)
对象构建发布:对象域写入和引用域写入,这两操作本身可以重排
初始化安全性:看到指针,能看到final域和final域可达对象(如final数组或hashmap里的内容),引用域写入不能排到对象构造(final域写入)之前,引用写入且刷新到主存前final域和final域可达变量一定刷新完毕了
事实不可变对象如Date,访问不需同步,安全发布就好
可变对象,安全发布,带安全机制访问

封装(数据和同步机制)更容易实现线程安全,在内部状态的访问路径上加锁,客户端也不用同步了
我们喜欢将线程安全性委托给一些不可变类,线程安全容器啊,但需考虑多变量的不变性条件
对组合模式(put if absent)的线程安全扩展

编译重排,处理器乱序执行,内存的重排序(就是CPU缓存导致的)
先写(处理器实际写)肯定先刷新,队列形式,当然我们不确定是否存在部分刷新

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值