java 并发编程学习(2)

来源:互联网 发布:最好的视频会议软件 编辑:程序博客网 时间:2024/05/18 15:52

1.可见性

可见性是指多个线程访问一个变量,一个线程修改了这个变量的值,其他线程能够立即访看到修改后的值

2.volatile变量

当把变量声明为volatile类型时,编译器和运行时都会注意到这个变量是共享的,不会将该变量上的操作和其他操作重排序,并且volatile变量不会被缓存在寄存器或者其他处理器不可见的地方,因此读取volatile类型的变量时,返回的总是最近写入的值。

加锁机制可以保证原子性和可见性,volatile变量只能确保可见性

当且仅当满足以下所有条件时,方可使用volatile

   a.对变量的写入不依赖与变量的当前值,或者保证仅有一个线程修改变量

   b.该变量不会与其他状态变量一起纳入不变性条件中

   c.访问变量时不需要加锁

3.线程封闭

仅在单线程内访问数据

   a.Ad-hoc线程封闭:维护线程封闭性的职责完全由程序实现来承担
   b.栈封闭:栈封闭式线程封闭的一种特例,在栈封闭中,只有通过局部变量才能访问对象。比Ad-hoc线程封闭更易于维护
   c.ThreadLocal类:当某个频繁执行的操作需要一个临时变量,同时又希望避免在每次执行时都重新分配该临时变量,可以使用这个技术
4.不变性
如果某个对象在被创建后其状态就不能被修改,那么就称这个对象是不可变对象
不可变对象一定是线程安全的
所有状态都是final类型仍不能保证该对象是不可变的,因为final类型的状态可以保存对可变对象的引用
当满足一下条件时,对象是不可变的
   a.对象创建后就其状态不能修改
   b.所有状态都是final类型
   c.对象是正确创建的(在对象创建期间,this应用没有逸出)
public class A {private final Set<String> set = new HashSet<String>();public A() {set.add("aaa");set.add("bbb");set.add("ccc");}public boolean isContain(String str) {return set.contains(str);}}
5.final域
用于构造不可变性对象,final类型的变量是不可修改的,但是如果final类型的变量保存的是可变对象的引用,被引用的对象是可以修改的
除非需要更高的可见性,否则把成员变量都声明为私有的,除非成员变量是可变的,否则都声明为final类型(非硬性要求)
6.安全发布的常用模式
一个正确构造的对象可以通过以下的方式来安全的发布:
   a.在静态初始化函数中初始化一个对象引用
   b.将对象的引用保存到volatile类型的域或者AtomicReferance对象中
   c.将对象的引用保存到某个正确构造对象的final类型域中
   d.将对象的引用保存到一个由锁保护的域中
对象的发布需求取决于他的可变性:
   a.不可变对象可以通过任意机制发布
   b.事实不可变对象必须通过安全方式发布
   c.可变对象必须通过安全方式发布,并且必须是线程安全的或者是由某个锁保护起来的
7.在并发程序中使用和共享对象时,可以使用一些实用的策略,包括:
   a.线程封闭:线程封闭的对象只能有一个线程拥有,对象被封闭在线程中,并且只能由这一个线程修改
   b.共享只读:在没有额外同步的情况下,共享的只读对象可以被多个线程并发访问,但是没有一个线程可以修改他。共享只读对象包括不可变对象和事实不可变对象
   c.线程安全共享:线程安全的对象在内部实现同步,因此多个线程可以通过对象的公共接口来进行访问,而不需要进一步的同步
   d.保护对象:被保护的对象只能通过持有特定的锁来访问。保护对象包括封装在其他线程安全对象中的对象,以及已发布并由某个特定所保护的对象
原创粉丝点击