《java 并发编程实战》对象共享笔记

 1.对象的可见性,是指对象的修改,对其他线程可见,具体的方法可以使用同步机制或者使用valatile 关键字防止jvm 虚拟机对指令就行重排序,为什么jvm 会对指令进行重排序,是因为重排序使得指令的执行变得紧凑

指令重排序:就是处理器处理汇编代码时,有依赖关系,导致下一个结果。需要上一个计算的结果

例如:a =b+c

      d=e-f 

   换算成汇编:是指: lw R1b  lwR2c  sadd a R1R2

    if id ex mem wb

       if id  ex mem wb

           if id 等待 ex mem wb

不安全的因素有:(1)失效的数据,例如一个pojo 类,一个线程修改了具体的属性,而另外一个线程读取的是原有的属性,导致出现无效的数据。(2) 非原子的64位操作,jvm 对long ,double 类型是分两个32位存储的,当读取一个非volatile long 类型时,可能一个线程写入了32位,另外一个线程读取时,就会读取写入的32位和另外一个32位,导致数据出现异常。

2.对象的发布与逃逸

发布一个对象是指:是当前对象能够在当前作用域之外访问,具体的有,将一个public 方法返回该对象或者是将该对象传递给一个方法中,对象的逃逸就是指,当某个对象在没有构造完成之前被发布了,这种想象就是对象的逃逸,例如this 逃逸,情况是在构造函数中构造了匿名类,此时这个匿名类就可以访问外围对象的this,在多线程的情况下,这个对象不一定构造完成,所以他不是线程安全的

3.线程封闭的

当访问共享的可变数据时,通常需要使用同步。一种避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步。这种技术被称为线程封闭

线程封闭的主要技术有,ad-hoc线程封闭,栈封闭和threadlocal 封闭

3.1 ad-hoc 线程封闭是指,维护线程封闭的职责完全有程序承担,这句话我的理解是,线程维护线程安全就是让程序猿自己去控制,

3.2 栈封闭,就是将数据放到方法中去,就是使用临时变量,不使用全局变量,因为jvm 虚拟机栈是线程私有的,每个线程都有一份自己的线程栈,他们是隔离的,但是要注意的是,不能让局部变量逃逸,如果局部变量逃逸,其他对象可以使用的话,不能保证线程的安全性,

3,3 threadlocal 封闭,就是将实例变量定义为threadLocal 类型,因为ThreadLocal 是保证了变量在每个线程都有一份副本,采用是空间换时间的概念,避免了使用线程同步导致的性能问题,ThreadLocal 是每个线程有一份,通过get 方法,获取线程的ThreadLocalMap ,讲当前threadlocal 对象作为key 值,进去查询的,所以每个线程都有自己的一份ThreadLocal对象 ,ThreadLocalMap 是采用弱类型的,利于JVM gc 回收,不用担心内存溢出问题,

猜你喜欢

转载自lliang54.iteye.com/blog/2384333