zoukankan      html  css  js  c++  java
  • java并发编程实战笔记---(第三章)对象的共享

    3.1 可见性

    synchronized 不仅实现了原子性操作或者确定了临界区,而且确保内存可见性

    *****必须在同步中才能保证:当一个线程修改了对象状态之后,另一个线程可以看到发生的状态变化。

    1.失效值问题

    以上类非线程安全,get和set在非同步情况下获取value值。

    当一个线程修改value,另一个线程可能得到更新后的值,也可能得不到。

    对get和set进行同步,可以是成为线程安全类。

    2. long或者double 需要用volatile修饰或者用锁保护。 因为64位值可能被拆为2个32位操作。

    3.volatile 修饰变量,确保获取最新值。

    加锁可以确保可见性和原子性,而volatile只能确保可见性。

     

    可以被写入 volatile 变量的这些有效值独立任何程序的状态包括变量的当前状态:

    • 对变量的写操作不依赖于当前值。
    • 该变量没有包含在具有其他变量的不变式中。

    lower upper非独立于其他状态

    3.2发布与逸出

    发布:对象能够在当前作用域之外的代码中使用。

    逸出: 某个不应该被发布的对象被发布。

     

     3.3线程封闭

     将某个对象封闭在某个线程中。举例:connection从线程池拿出给某个线程使用,且不会在分给其他线程。

    java及核心库提供支持:例如 局部变量和ThreadLocal

    但是程序员仍要确保封闭在线程中的对象不会从线程中逸出。

    2栈封闭

    局部变量的固有属性,就是封闭在执行的栈中。其他线程无法访问这个栈。但是编程要确保不逸出。

     开发人员要给出注释那些对象需要封闭到执行线程中,便于以后维护时不会造成逸出。

    3.threadlocal

    3.4不变性

    不可变对象一定是线程安全的。

    满足以下条件时,对象才不可变:

    1.对象创建以后其状态就不能修改。

    2.对象的所有域都是final类型。

    3.对象是正确创建的(对象的创建期间,this引用没有逸出)。

    1.Final域

    2.volatile类型来发布不可变对象(volatile+不可变对象)

    当需要对一组数据以原子方式执行某些操作时,可以考虑创建一个不可变类来封装这些数据。如上例。

    对于在访问和更新多个相关变量时出现的竞争性条件,通过将这些变量保存在一个不可变类中来消除。不可变对象,当线程获得该变量引用后,不必担心其他线程会修改该对象的状态。如果要更新该对象,可以创建    一个新的容器对象   。其他线程没有影响。

    总结:将变化的封装在一个不变的容器类中,讲内容的变化改为创建一个新的容器。

     

     3.5安全发布

    上面讨论的是如何让对象不被发布,讲对象封闭在线程或者另一个对象中。但是有时需要在线程中共享对象,所以需要安全发布对象。

    //在没有足够同步的情况下发布对象,不要这么做

    public Holder holder;

    public void intialize() {

      holder =  new Holder(42);

    }

    存在可见性问题,其他线程看到未被完全创建的对象。

    1.不正确的发布:正确的对象被破坏

    class Holder{

      private int n;

      public Holder(int n) {  this.n = n; }

      public void assertSanity() {

        if( n != n) {

          throw new AssertionError("this statement is error");

        }

      }

    }

    2.安全发布的常用模式: 

     

     

     3.事实不可变对象:

    如果对象的状态在发布后不会在改变,称为事实不可变状态。

     

     *********

     

     线程安全共享:此类内部实现同步。

     保护对象:使用时加锁。

  • 相关阅读:
    hdu-1142(记忆化搜索+dij)
    hdu-1140(求距离,精度判断)
    hdu-1131(卡特兰数+大数)
    hdu-1130(卡特兰数+大数乘法,除法模板)
    hdu-1129(模拟题)
    hdu-1128(数学问题,筛数)
    hdu-1124(数学问题,求n!的尾零的个数)
    hdu-1115(计算多边形重心)
    hdu-1121(差分法--数学问题)
    表达式求值(堆栈)
  • 原文地址:https://www.cnblogs.com/wuer888/p/6932443.html
Copyright © 2011-2022 走看看