本文共 1833 字,大约阅读时间需要 6 分钟。
缺乏同步可能产生:失效数据
最低安全性:当线程在没有同步的情况下读取变量时,可能得到一个失效值,但至少是之前某个线程设置的值,而不是一个随机值
最低安全性的例外:非volatile类型的64位数值变量,所以多线程共享可变的long和double等类型的变量是不安全的,除非用volatile声明,或用锁保护起来
加锁的含义不仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或写操作的线程都必须在同一个锁上同步
访问volatile变量不会执行加锁操作,也就不会是执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制
加锁可以确保可见性与原子性,volatile只能确保可见性
当且仅当满足以下所有条件才应该用volatile:
发布对象:使对象能在当前作用域之外的代码中使用
发布对象的方法:
外部方法:对类C来说,外部方法指行为不完全由C来规定的方法,包括其它类中定义的方法和C中可以被改写的方法(不是private或final的方法)
this引用逸出的几种情况:
在构造函数中引入了一个内部类EventListener,而内部类会自动的持有其外部类(这里是ThisEscape)this引用。source.registerListener会将内部类发布出去,从而ThisEscape.this引用也随着内部类被发布了出去。
构造函数中启动一个线程,this引用会被新创建的线程共享
在构造函数中调用一个可改写的实例方法(既不是私有方法,又不是final方法)
Ad-hoc线程封闭:维护线程封闭性的职责完全由程序实现来承担(很脆弱,尽量少用)
栈封闭:只能通过局部变量访问对象,多个线程访问一个方法,此方法中的局部变量都会被拷贝一份到线程栈中。所以局部变量是不被多个线程所共享的,也就不会出现并发问题
ThreadLocal类:使线程中某个值与保存值的对象关联起来,为每个使用该变量的线程存有一份独立的副本,防止对可变的单实例变量或全局变量进行共享
满足以下条件的对象才是不可变的:
不可变对象内部仍然可以使用可变对象来管理他们的状态
不可变对象vs不可变的对象引用:保存在不可变对象中的程序状态仍然可以更新,即通过一个保存新状态的实例来替换原有的不可变对象
一个正确构造的对象可以通过以下方式安全发布:
线程安全容器的安全发布保证:
事实不可变对象:对象从技术上看是可变的,但其状态在发布后不会改变
对象的发布需求取决于它的可变性:
并发程序中使用和共享对象,实用策略:
转载地址:http://qlkvb.baihongyu.com/