美文网首页
java并发编程: 基础部分

java并发编程: 基础部分

作者: 神之试炼者 | 来源:发表于2018-02-07 15:31 被阅读21次

    捡重要的记录

    目的

    充分利用系统资源. 提升程序性能.
    
    常见问题:
    线程A和线程B同时更新value
     @NotThreadSafe      这只是个说明性注解, 并不保证类的线程安全性, 安全性要自己实现
     public class UnsafeSequence{
         private int value;
         public int getNext(){ 
             return value++;
          } 
    }
    

    用synchronized修正上面的代码:

     @ThreadSafe      //记住这个只是文档性注解,安全性要自己实现
     public class UnsafeSequence{
       @GuardedBy("this")    // 指明value的一致性由对象自己负责
       private int value;
    
       public synchronized int getNext(){  
          return value++;  
      }
    }
    

    常见文档性注解说明:

    下面都是文档性注解, 不要指望加这类注解就实现一致性.

    类注解:
    @ThreadSafe,
    @NotThreadSafe,
    @Immutable
        描述该类是不可变的. immutable的类自然是threadsafe的.
    域注解和方法注解:
    @GardedBy(lock)
        lock可以是:"this", "fieldName", "ClassName.fieldName","methodName()","ClassName.class"
        描述该域(或方法)的一致性应该由某个属性保证


    文档注解的好处:

    1. 使用者一眼就知道类的特性
    2. 维护者需要根据这个协定保证并发特性
    3. 一些代码分析工具根据这些注解验证类实现是否和文档一致
    4. 能通过文档性注解展示锁和状态保护, 哪天代码改变了状态(新增域或方法), 能通过文档提醒修改者注意保证并发特性.

    多线程中额外的性能损耗: 上下文切换的损耗

    java中首要的同步机制是:

    synchronized, volatile,显示锁和原子变量

    三种方案解决多线程问题:
    1. 不要跨线程共享便变量;
    2. 使共享变量不可变;
    3. 在任何访问状态变量的时候使用同步;

    相比同步, 良好的设计更重要!!!

    完全由线程安全类构成的程序未必是线程安全的....只有当类封装了自己的状态时. "线程安全类"才有意义.

    无状态对象永远是线程安全的
    比如servlet, 再比如spring的单例模式, 虽然是有状态的, 但是如果状态变量没有修改操作. 仍然是线程安全的.

    count++;
    自增操作看上去是单独的, 实际上却是3个离散操作的简写:
    读 - 改 - 写

      //java自带的线程安全计数器
      private final AtomicLong count = new AtomicLong(0);
    

    volatile: 弱同步
    确保对一个变量的更新以可预见的方式告知其他线程
    原理:
    编译器和运行时会监听volatile修饰的变量: 它是共享的, 对它的操作不会与其他的内存操作一起被重排序, volatile变量不会缓存在寄存器, 也不会缓存在其他处理器看不到的地方. 所以, 读volatile变量的时候总能读到某个线程写入的最新值.

    volatile关键字 不足以支持自操作的原子性!

    ThreadLocal:每个线程会维护一份自己的拷贝, 从而实现线程封闭

    不可变对象永远是线程安全的.

    To Be Continued...

    相关文章

      网友评论

          本文标题:java并发编程: 基础部分

          本文链接:https://www.haomeiwen.com/subject/hidozxtx.html